Merge branch 'master' into macro-values-fix
This commit is contained in:
commit
95b0b25011
84 changed files with 540 additions and 211 deletions
|
|
@ -411,6 +411,13 @@ class DivDispatch {
|
|||
*/
|
||||
virtual DivMacroInt* getChanMacroInt(int chan);
|
||||
|
||||
/**
|
||||
* get the stereo panning of a channel.
|
||||
* @param chan the channel.
|
||||
* @return a 16-bit number. left in top 8 bits and right in bottom 8 bits.
|
||||
*/
|
||||
virtual unsigned short getPan(int chan);
|
||||
|
||||
/**
|
||||
* get currently playing sample (and its position).
|
||||
* @param chan the channel.
|
||||
|
|
|
|||
|
|
@ -1279,6 +1279,11 @@ DivChannelState* DivEngine::getChanState(int ch) {
|
|||
return &chan[ch];
|
||||
}
|
||||
|
||||
unsigned short DivEngine::getChanPan(int ch) {
|
||||
if (ch<0 || ch>=chans) return 0;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->getPan(dispatchChanOfChan[ch]);
|
||||
}
|
||||
|
||||
void* DivEngine::getDispatchChanState(int ch) {
|
||||
if (ch<0 || ch>=chans) return NULL;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->getChanState(dispatchChanOfChan[ch]);
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@
|
|||
|
||||
#define DIV_UNSTABLE
|
||||
|
||||
#define DIV_VERSION "dev167"
|
||||
#define DIV_ENGINE_VERSION 167
|
||||
#define DIV_VERSION "dev168"
|
||||
#define DIV_ENGINE_VERSION 168
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
|
@ -976,6 +976,9 @@ class DivEngine {
|
|||
// get macro interpreter
|
||||
DivMacroInt* getMacroInt(int chan);
|
||||
|
||||
// get channel panning
|
||||
unsigned short getChanPan(int chan);
|
||||
|
||||
// get sample position
|
||||
DivSamplePos getSamplePos(int chan);
|
||||
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.brokenPortaArp=false;
|
||||
ds.snNoLowPeriods=true;
|
||||
ds.disableSampleMacro=true;
|
||||
ds.preNoteNoEffect=true;
|
||||
ds.delayBehavior=0;
|
||||
ds.jumpTreatment=2;
|
||||
|
||||
|
|
@ -1844,6 +1845,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
if (ds.version<155) {
|
||||
ds.brokenFMOff=true;
|
||||
}
|
||||
if (ds.version<168) {
|
||||
ds.preNoteNoEffect=true;
|
||||
}
|
||||
ds.isDMF=false;
|
||||
|
||||
reader.readS(); // reserved
|
||||
|
|
@ -2355,7 +2359,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<6; i++) {
|
||||
if (ds.version>=168) {
|
||||
ds.preNoteNoEffect=reader.readC();
|
||||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<5; i++) {
|
||||
reader.readC();
|
||||
}
|
||||
}
|
||||
|
|
@ -5383,7 +5392,9 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
|||
|
||||
// even more compat flags
|
||||
w->writeC(song.brokenPortaLegato);
|
||||
for (int i=0; i<7; i++) {
|
||||
w->writeC(song.brokenFMOff);
|
||||
w->writeC(song.preNoteNoEffect);
|
||||
for (int i=0; i<5; i++) {
|
||||
w->writeC(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ void* DivDispatch::getChanState(int chan) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
unsigned short DivDispatch::getPan(int chan) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DivMacroInt* DivDispatch::getChanMacroInt(int chan) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -857,6 +857,10 @@ DivMacroInt* DivPlatformArcade::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformArcade::getPan(int ch) {
|
||||
return (chan[ch].chVolL<<8)|(chan[ch].chVolR);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformArcade::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ class DivPlatformArcade: public DivPlatformOPM {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
void notifyInsChange(int ins);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void setFlags(const DivConfig& flags);
|
||||
|
|
|
|||
|
|
@ -344,6 +344,10 @@ DivMacroInt* DivPlatformC140::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformC140::getPan(int ch) {
|
||||
return (chan[ch].chPanL<<8)|(chan[ch].chPanR);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformC140::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ class DivPlatformC140: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -1057,6 +1057,10 @@ DivMacroInt* DivPlatformES5506::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformES5506::getPan(int ch) {
|
||||
return ((chan[ch].lVol>>4)<<8)|(chan[ch].rVol>>4);
|
||||
}
|
||||
|
||||
void DivPlatformES5506::reset() {
|
||||
while (!hostIntf32.empty()) hostIntf32.pop();
|
||||
while (!hostIntf8.empty()) hostIntf8.pop();
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
|
|||
virtual int dispatch(DivCommand c) override;
|
||||
virtual void* getChanState(int chan) override;
|
||||
virtual DivMacroInt* getChanMacroInt(int ch) override;
|
||||
virtual unsigned short getPan(int chan) override;
|
||||
virtual DivDispatchOscBuffer* getOscBuffer(int chan) override;
|
||||
virtual unsigned char* getRegisterPool() override;
|
||||
virtual int getRegisterPoolSize() override;
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ class DivPlatformOPN: public DivPlatformFMBase {
|
|||
unsigned int ayDiv;
|
||||
unsigned char csmChan;
|
||||
unsigned char lfoValue;
|
||||
unsigned char lastExtChPan;
|
||||
unsigned short ssgVol;
|
||||
unsigned short fmVol;
|
||||
bool extSys, useCombo, fbAllOps;
|
||||
|
|
@ -175,6 +176,7 @@ class DivPlatformOPN: public DivPlatformFMBase {
|
|||
ayDiv(a),
|
||||
csmChan(cc),
|
||||
lfoValue(0),
|
||||
lastExtChPan(3),
|
||||
ssgVol(128),
|
||||
fmVol(256),
|
||||
extSys(isExtSys),
|
||||
|
|
|
|||
|
|
@ -578,6 +578,11 @@ DivMacroInt* DivPlatformGB::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformGB::getPan(int ch) {
|
||||
unsigned char p=lastPan&(0x11<<ch);
|
||||
return ((p&0xf0)?0x100:0)|((p&0x0f)?1:0);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformGB::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ class DivPlatformGB: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -1274,6 +1274,11 @@ DivMacroInt* DivPlatformGenesis::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformGenesis::getPan(int ch) {
|
||||
if (ch>5) ch=5;
|
||||
return ((chan[ch].pan&2)<<7)|(chan[ch].pan&1);
|
||||
}
|
||||
|
||||
DivSamplePos DivPlatformGenesis::getSamplePos(int ch) {
|
||||
if (!chan[5].dacMode) return DivSamplePos();
|
||||
if (ch<5) return DivSamplePos();
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
virtual unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
rWrite(chanOffs[2]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[2].state.fms&7)|((chan[2].state.ams&3)<<4));
|
||||
lastExtChPan=opChan[ch].pan;
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
|
|
@ -756,7 +757,7 @@ void DivPlatformGenesisExt::forceIns() {
|
|||
}
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
if (i==2) {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_EXTCH_MUTED?0:(opChan[0].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_EXTCH_MUTED?0:(lastExtChPan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
} else {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
|
|
@ -800,6 +801,19 @@ DivMacroInt* DivPlatformGenesisExt::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformGenesisExt::getPan(int ch) {
|
||||
if (ch==csmChan) return 0;
|
||||
if (ch>=4+extChanOffs) return DivPlatformGenesis::getPan(ch-3);
|
||||
if (ch>=extChanOffs) {
|
||||
if (extMode) {
|
||||
return ((lastExtChPan&2)<<7)|(lastExtChPan&1);
|
||||
} else {
|
||||
return DivPlatformGenesis::getPan(extChanOffs);
|
||||
}
|
||||
}
|
||||
return DivPlatformGenesis::getPan(ch);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformGenesisExt::getOscBuffer(int ch) {
|
||||
if (ch>=6) return oscBuf[ch-3];
|
||||
if (ch<3) return oscBuf[ch];
|
||||
|
|
@ -816,6 +830,8 @@ void DivPlatformGenesisExt::reset() {
|
|||
opChan[i].outVol=127;
|
||||
}
|
||||
|
||||
lastExtChPan=3;
|
||||
|
||||
// channel 3 mode
|
||||
immWrite(0x27,0x40);
|
||||
extMode=true;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
void reset();
|
||||
void forceIns();
|
||||
|
|
|
|||
|
|
@ -424,6 +424,10 @@ DivMacroInt* DivPlatformK007232::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformK007232::getPan(int ch) {
|
||||
return ((chan[ch].panning&15)<<8)|((chan[ch].panning&0xf0)>>4);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformK007232::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -370,6 +370,10 @@ DivMacroInt* DivPlatformK053260::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformK053260::getPan(int ch) {
|
||||
return parent->convertPanLinearToSplit(chan[ch].panning,8,7);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformK053260::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
|
|||
virtual int dispatch(DivCommand c) override;
|
||||
virtual void* getChanState(int chan) override;
|
||||
virtual DivMacroInt* getChanMacroInt(int ch) override;
|
||||
virtual unsigned short getPan(int chan) override;
|
||||
virtual DivDispatchOscBuffer* getOscBuffer(int chan) override;
|
||||
virtual unsigned char* getRegisterPool() override;
|
||||
virtual int getRegisterPoolSize() override;
|
||||
|
|
|
|||
|
|
@ -430,6 +430,10 @@ DivMacroInt* DivPlatformLynx::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformLynx::getPan(int ch) {
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivSamplePos DivPlatformLynx::getSamplePos(int ch) {
|
||||
if (ch>=4) return DivSamplePos();
|
||||
if (!chan[ch].pcm) return DivSamplePos();
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class DivPlatformLynx: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
|
|
|
|||
|
|
@ -282,6 +282,10 @@ DivMacroInt* DivPlatformMSM6258::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformMSM6258::getPan(int ch) {
|
||||
return ((chan[ch].pan&2)<<7)|(chan[ch].pan&1);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformMSM6258::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class DivPlatformMSM6258: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -473,6 +473,11 @@ DivMacroInt* DivPlatformNamcoWSG::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformNamcoWSG::getPan(int ch) {
|
||||
if (devType!=30) return 0;
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformNamcoWSG::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class DivPlatformNamcoWSG: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -1564,6 +1564,18 @@ DivMacroInt* DivPlatformOPL::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformOPL::getPan(int ch) {
|
||||
if (totalOutputs<=1) return 0;
|
||||
/*if (chan[ch&(~1)].fourOp) {
|
||||
if (ch&1) {
|
||||
return ((chan[ch-1].pan&2)<<7)|(chan[ch-1].pan&1);
|
||||
} else {
|
||||
return ((chan[ch+1].pan&2)<<7)|(chan[ch+1].pan&1);
|
||||
}
|
||||
}*/
|
||||
return ((chan[ch].pan&1)<<8)|((chan[ch].pan&2)>>1);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformOPL::getOscBuffer(int ch) {
|
||||
if (oplType==759 || chipType==8950) {
|
||||
if (ch>=totalChans+1) return NULL;
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -508,6 +508,10 @@ DivMacroInt* DivPlatformPCE::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformPCE::getPan(int ch) {
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivSamplePos DivPlatformPCE::getSamplePos(int ch) {
|
||||
if (ch>=6) return DivSamplePos();
|
||||
if (!chan[ch].pcm) return DivSamplePos();
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ class DivPlatformPCE: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
|
|
|
|||
|
|
@ -497,6 +497,10 @@ DivMacroInt* DivPlatformPCMDAC::getChanMacroInt(int ch) {
|
|||
return &chan[0].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformPCMDAC::getPan(int ch) {
|
||||
return (chan[0].panL<<8)|chan[0].panR;
|
||||
}
|
||||
|
||||
DivSamplePos DivPlatformPCMDAC::getSamplePos(int ch) {
|
||||
if (ch>=1) return DivSamplePos();
|
||||
return DivSamplePos(
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ class DivPlatformPCMDAC: public DivDispatch {
|
|||
void muteChannel(int ch, bool mute);
|
||||
int getOutputCount();
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsChange(int ins);
|
||||
|
|
|
|||
|
|
@ -623,6 +623,10 @@ DivMacroInt* DivPlatformQSound::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformQSound::getPan(int ch) {
|
||||
return parent->convertPanLinearToSplit(chan[ch].panning,8,32);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformQSound::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class DivPlatformQSound: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -322,6 +322,10 @@ DivMacroInt* DivPlatformRF5C68::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformRF5C68::getPan(int ch) {
|
||||
return ((chan[ch].panning&15)<<8)|((chan[ch].panning&0xf0)>>4);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformRF5C68::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ class DivPlatformRF5C68: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -365,6 +365,10 @@ DivMacroInt* DivPlatformSAA1099::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformSAA1099::getPan(int ch) {
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformSAA1099::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ class DivPlatformSAA1099: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -394,6 +394,10 @@ DivMacroInt* DivPlatformSegaPCM::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformSegaPCM::getPan(int ch) {
|
||||
return (chan[ch].chPanL<<8)|chan[ch].chPanR;
|
||||
}
|
||||
|
||||
DivSamplePos DivPlatformSegaPCM::getSamplePos(int ch) {
|
||||
if (ch>=16) return DivSamplePos();
|
||||
if (chan[ch].pcm.sample<0 || chan[ch].pcm.sample>=parent->song.sampleLen) return DivSamplePos();
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ class DivPlatformSegaPCM: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
|
|
|
|||
|
|
@ -452,6 +452,12 @@ DivMacroInt* DivPlatformSMS::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformSMS::getPan(int ch) {
|
||||
if (!stereo) return 0;
|
||||
unsigned char p=lastPan&(0x11<<ch);
|
||||
return ((p&0xf0)?0x100:0)|((p&0x0f)?1:0);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformSMS::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class DivPlatformSMS: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -699,6 +699,10 @@ DivMacroInt* DivPlatformSNES::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformSNES::getPan(int ch) {
|
||||
return (chan[ch].panL<<8)|chan[ch].panR;
|
||||
}
|
||||
|
||||
DivSamplePos DivPlatformSNES::getSamplePos(int ch) {
|
||||
if (ch>=8) return DivSamplePos();
|
||||
if (!chan[ch].active) return DivSamplePos();
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ class DivPlatformSNES: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
|
|
|
|||
|
|
@ -458,6 +458,10 @@ DivMacroInt* DivPlatformSoundUnit::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformSoundUnit::getPan(int ch) {
|
||||
return parent->convertPanLinearToSplit(chan[ch].pan,8,255);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformSoundUnit::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ class DivPlatformSoundUnit: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -476,6 +476,10 @@ DivMacroInt* DivPlatformSwan::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformSwan::getPan(int ch) {
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformSwan::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class DivPlatformSwan: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -300,6 +300,10 @@ DivMacroInt* DivPlatformT6W28::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformT6W28::getPan(int ch) {
|
||||
return (chan[ch].panL<<8)|chan[ch].panR;
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformT6W28::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ class DivPlatformT6W28: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -965,6 +965,10 @@ DivMacroInt* DivPlatformTX81Z::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformTX81Z::getPan(int ch) {
|
||||
return (chan[ch].chVolL<<8)|(chan[ch].chVolR);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformTX81Z::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class DivPlatformTX81Z: public DivPlatformOPM {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -419,6 +419,10 @@ DivMacroInt* DivPlatformVB::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformVB::getPan(int ch) {
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformVB::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ class DivPlatformVB: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -444,6 +444,10 @@ DivMacroInt* DivPlatformVERA::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformVERA::getPan(int ch) {
|
||||
return ((chan[ch].pan&1)<<8)|((chan[ch].pan&2)>>1);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformVERA::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class DivPlatformVERA: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -863,6 +863,11 @@ DivMacroInt* DivPlatformX1_010::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformX1_010::getPan(int ch) {
|
||||
if (!stereo) return 0;
|
||||
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformX1_010::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ class DivPlatformX1_010: public DivDispatch, public vgsound_emu_mem_intf {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -1461,6 +1461,11 @@ DivMacroInt* DivPlatformYM2608::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYM2608::getPan(int ch) {
|
||||
if (ch>=psgChanOffs && ch<adpcmAChanOffs) return 0;
|
||||
return ((chan[ch].pan&2)<<7)|(chan[ch].pan&1);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYM2608::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class DivPlatformYM2608: public DivPlatformOPN {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
virtual unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
rWrite(chanOffs[2]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[2].state.fms&7)|((chan[2].state.ams&3)<<4));
|
||||
lastExtChPan=opChan[ch].pan;
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
|
|
@ -750,6 +751,18 @@ DivMacroInt* DivPlatformYM2608Ext::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYM2608Ext::getPan(int ch) {
|
||||
if (ch>=4+extChanOffs) return DivPlatformYM2608::getPan(ch-3);
|
||||
if (ch>=extChanOffs) {
|
||||
if (extMode) {
|
||||
return ((lastExtChPan&2)<<7)|(lastExtChPan&1);
|
||||
} else {
|
||||
return DivPlatformYM2608::getPan(extChanOffs);
|
||||
}
|
||||
}
|
||||
return DivPlatformYM2608::getPan(ch);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYM2608Ext::getOscBuffer(int ch) {
|
||||
if (ch>=6) return oscBuf[ch-3];
|
||||
if (ch<3) return oscBuf[ch];
|
||||
|
|
@ -766,7 +779,9 @@ void DivPlatformYM2608Ext::reset() {
|
|||
opChan[i].outVol=127;
|
||||
}
|
||||
|
||||
// channel 2 mode
|
||||
lastExtChPan=3;
|
||||
|
||||
// channel 3 mode
|
||||
immWrite(0x27,0x40);
|
||||
extMode=true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class DivPlatformYM2608Ext: public DivPlatformYM2608 {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
void reset();
|
||||
void forceIns();
|
||||
|
|
|
|||
|
|
@ -1421,6 +1421,11 @@ DivMacroInt* DivPlatformYM2610::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYM2610::getPan(int ch) {
|
||||
if (ch>=psgChanOffs && ch<adpcmAChanOffs) return 0;
|
||||
return ((chan[ch].pan&2)<<7)|(chan[ch].pan&1);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYM2610::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class DivPlatformYM2610: public DivPlatformYM2610Base {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
virtual unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -1488,6 +1488,11 @@ DivMacroInt* DivPlatformYM2610B::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYM2610B::getPan(int ch) {
|
||||
if (ch>=psgChanOffs && ch<adpcmAChanOffs) return 0;
|
||||
return ((chan[ch].pan&2)<<7)|(chan[ch].pan&1);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYM2610B::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class DivPlatformYM2610B: public DivPlatformYM2610Base {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
virtual unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
rWrite(chanOffs[extChanOffs]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[extChanOffs].state.fms&7)|((chan[extChanOffs].state.ams&3)<<4));
|
||||
lastExtChPan=opChan[ch].pan;
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
|
|
@ -695,7 +696,7 @@ void DivPlatformYM2610BExt::forceIns() {
|
|||
}
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
if (i==extChanOffs) {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_EXTCH_MUTED?0:(opChan[0].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_EXTCH_MUTED?0:(lastExtChPan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
} else {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
|
|
@ -740,6 +741,18 @@ DivMacroInt* DivPlatformYM2610BExt::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYM2610BExt::getPan(int ch) {
|
||||
if (ch>=4+extChanOffs) return DivPlatformYM2610B::getPan(ch-3);
|
||||
if (ch>=extChanOffs) {
|
||||
if (extMode) {
|
||||
return ((lastExtChPan&2)<<7)|(lastExtChPan&1);
|
||||
} else {
|
||||
return DivPlatformYM2610B::getPan(extChanOffs);
|
||||
}
|
||||
}
|
||||
return DivPlatformYM2610B::getPan(ch);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYM2610BExt::getOscBuffer(int ch) {
|
||||
if (ch>=(extChanOffs+4)) return oscBuf[ch-3];
|
||||
if (ch<(extChanOffs+1)) return oscBuf[ch];
|
||||
|
|
@ -756,7 +769,9 @@ void DivPlatformYM2610BExt::reset() {
|
|||
opChan[i].outVol=127;
|
||||
}
|
||||
|
||||
// channel 2 mode
|
||||
lastExtChPan=3;
|
||||
|
||||
// channel 3 mode
|
||||
immWrite(0x27,0x40);
|
||||
extMode=true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class DivPlatformYM2610BExt: public DivPlatformYM2610B {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
void reset();
|
||||
void forceIns();
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
rWrite(chanOffs[extChanOffs]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[extChanOffs].state.fms&7)|((chan[extChanOffs].state.ams&3)<<4));
|
||||
lastExtChPan=opChan[ch].pan;
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_PITCH: {
|
||||
|
|
@ -695,7 +696,7 @@ void DivPlatformYM2610Ext::forceIns() {
|
|||
}
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
if (i==extChanOffs) {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_EXTCH_MUTED?0:(opChan[0].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_EXTCH_MUTED?0:(lastExtChPan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
} else {
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
|
|
@ -740,6 +741,18 @@ DivMacroInt* DivPlatformYM2610Ext::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYM2610Ext::getPan(int ch) {
|
||||
if (ch>=4+extChanOffs) return DivPlatformYM2610::getPan(ch-3);
|
||||
if (ch>=extChanOffs) {
|
||||
if (extMode) {
|
||||
return ((lastExtChPan&2)<<7)|(lastExtChPan&1);
|
||||
} else {
|
||||
return DivPlatformYM2610::getPan(extChanOffs);
|
||||
}
|
||||
}
|
||||
return DivPlatformYM2610::getPan(ch);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYM2610Ext::getOscBuffer(int ch) {
|
||||
if (ch>=(extChanOffs+4)) return oscBuf[ch-3];
|
||||
if (ch<(extChanOffs+1)) return oscBuf[ch];
|
||||
|
|
@ -756,6 +769,8 @@ void DivPlatformYM2610Ext::reset() {
|
|||
opChan[i].outVol=127;
|
||||
}
|
||||
|
||||
lastExtChPan=3;
|
||||
|
||||
// channel 2 mode
|
||||
immWrite(0x27,0x40);
|
||||
extMode=true;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class DivPlatformYM2610Ext: public DivPlatformYM2610 {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
void reset();
|
||||
void forceIns();
|
||||
|
|
|
|||
|
|
@ -359,6 +359,10 @@ DivMacroInt* DivPlatformYMZ280B::getChanMacroInt(int ch) {
|
|||
return &chan[ch].std;
|
||||
}
|
||||
|
||||
unsigned short DivPlatformYMZ280B::getPan(int ch) {
|
||||
return parent->convertPanLinearToSplit(chan[ch].panning,8,15);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformYMZ280B::getOscBuffer(int ch) {
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ class DivPlatformYMZ280B: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
|
|
|
|||
|
|
@ -1208,8 +1208,26 @@ void DivEngine::nextRow() {
|
|||
if (disCont[dispatchOfChan[i]].dispatch!=NULL) {
|
||||
wantPreNote=disCont[dispatchOfChan[i]].dispatch->getWantPreNote();
|
||||
if (wantPreNote) {
|
||||
bool doPreparePreNote=true;
|
||||
int addition=0;
|
||||
|
||||
for (int j=0; j<curPat[i].effectCols; j++) {
|
||||
if (!song.preNoteNoEffect) {
|
||||
if (pat->data[curRow][4+(j<<1)]==0x03) {
|
||||
doPreparePreNote=false;
|
||||
break;
|
||||
}
|
||||
if (pat->data[curRow][4+(j<<1)]==0x06) {
|
||||
doPreparePreNote=false;
|
||||
break;
|
||||
}
|
||||
if (pat->data[curRow][4+(j<<1)]==0xea) {
|
||||
if (pat->data[curRow][5+(j<<1)]>0) {
|
||||
doPreparePreNote=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pat->data[curRow][4+(j<<1)]==0xed) {
|
||||
if (pat->data[curRow][5+(j<<1)]>0) {
|
||||
addition=pat->data[curRow][5+(j<<1)]&255;
|
||||
|
|
@ -1217,7 +1235,7 @@ void DivEngine::nextRow() {
|
|||
}
|
||||
}
|
||||
}
|
||||
dispatchCmd(DivCommand(DIV_CMD_PRE_NOTE,i,ticks+addition));
|
||||
if (doPreparePreNote) dispatchCmd(DivCommand(DIV_CMD_PRE_NOTE,i,ticks+addition));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -375,6 +375,7 @@ struct DivSong {
|
|||
bool patchbayAuto;
|
||||
bool brokenPortaLegato;
|
||||
bool brokenFMOff;
|
||||
bool preNoteNoEffect;
|
||||
|
||||
std::vector<DivInstrument*> ins;
|
||||
std::vector<DivWavetable*> wave;
|
||||
|
|
@ -493,7 +494,8 @@ struct DivSong {
|
|||
oldArpStrategy(false),
|
||||
patchbayAuto(true),
|
||||
brokenPortaLegato(false),
|
||||
brokenFMOff(false) {
|
||||
brokenFMOff(false),
|
||||
preNoteNoEffect(false) {
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
system[i]=DIV_SYSTEM_NULL;
|
||||
systemVol[i]=1.0;
|
||||
|
|
|
|||
|
|
@ -374,7 +374,9 @@ void FurnaceGUI::moveCursorNextChannel(bool overflow) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::moveCursorTop(bool select) {
|
||||
finishSelection();
|
||||
if (!select) {
|
||||
finishSelection();
|
||||
}
|
||||
curNibble=false;
|
||||
if (cursor.y==0) {
|
||||
DETERMINE_FIRST;
|
||||
|
|
@ -384,16 +386,18 @@ void FurnaceGUI::moveCursorTop(bool select) {
|
|||
} else {
|
||||
cursor.y=0;
|
||||
}
|
||||
selStart=cursor;
|
||||
if (!select) {
|
||||
selEnd=cursor;
|
||||
selStart=cursor;
|
||||
}
|
||||
selEnd=cursor;
|
||||
e->setMidiBaseChan(cursor.xCoarse);
|
||||
updateScroll(cursor.y);
|
||||
}
|
||||
|
||||
void FurnaceGUI::moveCursorBottom(bool select) {
|
||||
finishSelection();
|
||||
if (!select) {
|
||||
finishSelection();
|
||||
}
|
||||
curNibble=false;
|
||||
if (cursor.y==e->curSubSong->patLen-1) {
|
||||
DETERMINE_LAST;
|
||||
|
|
|
|||
|
|
@ -105,8 +105,10 @@ void FurnaceGUI::insListItem(int i, int dir, int asset) {
|
|||
bool insPressed=ImGui::IsItemActivated();
|
||||
if (insReleased || (!insListDir && insPressed)) {
|
||||
curIns=i;
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
if (!insReleased || insListDir) {
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
}
|
||||
lastAssetType=0;
|
||||
if (settings.insFocusesPattern && patternOpen)
|
||||
nextWindow=GUI_WINDOW_PATTERN;
|
||||
|
|
@ -892,15 +894,11 @@ void FurnaceGUI::drawSampleList(bool asChild) {
|
|||
doAction(GUI_ACTION_SAMPLE_LIST_PREVIEW);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Preview");
|
||||
ImGui::SetTooltip("Preview (right click to stop)");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_VOLUME_OFF "##StopSampleL")) {
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
doAction(GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Stop preview");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
pushDestColor();
|
||||
if (ImGui::Button(ICON_FA_TIMES "##SampleDelete")) {
|
||||
|
|
|
|||
|
|
@ -308,6 +308,21 @@ void FurnaceGUI::drawDebug() {
|
|||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Do Action")) {
|
||||
char bindID[1024];
|
||||
for (int j=0; j<GUI_ACTION_MAX; j++) {
|
||||
if (strcmp(guiActions[j].friendlyName,"")==0) continue;
|
||||
if (strstr(guiActions[j].friendlyName,"---")==guiActions[j].friendlyName) {
|
||||
ImGui::TextUnformatted(guiActions[j].friendlyName);
|
||||
} else {
|
||||
snprintf(bindID,1024,"%s##DO_%d",guiActions[j].friendlyName,j);
|
||||
if (ImGui::Button(bindID)) {
|
||||
doAction(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Pitch Table Calculator")) {
|
||||
ImGui::InputDouble("Clock",&ptcClock);
|
||||
ImGui::InputDouble("Divider/FreqBase",&ptcDivider);
|
||||
|
|
|
|||
|
|
@ -5279,180 +5279,199 @@ void FurnaceGUI::drawInsEdit() {
|
|||
if (ImGui::Checkbox("Enable synthesizer",&ins->ws.enabled)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ins->ws.effect&0x80) {
|
||||
if ((ins->ws.effect&0x7f)>=DIV_WS_DUAL_MAX) {
|
||||
ins->ws.effect=0;
|
||||
if (ins->ws.enabled) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ins->ws.effect&0x80) {
|
||||
if ((ins->ws.effect&0x7f)>=DIV_WS_DUAL_MAX) {
|
||||
ins->ws.effect=0;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
} else {
|
||||
if ((ins->ws.effect&0x7f)>=DIV_WS_SINGLE_MAX) {
|
||||
ins->ws.effect=0;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginCombo("##WSEffect",(ins->ws.effect&0x80)?dualWSEffects[ins->ws.effect&0x7f]:singleWSEffects[ins->ws.effect&0x7f])) {
|
||||
ImGui::Text("Single-waveform");
|
||||
ImGui::Indent();
|
||||
for (int i=0; i<DIV_WS_SINGLE_MAX; i++) {
|
||||
if (ImGui::Selectable(singleWSEffects[i])) {
|
||||
ins->ws.effect=i;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::Text("Dual-waveform");
|
||||
ImGui::Indent();
|
||||
for (int i=129; i<DIV_WS_DUAL_MAX; i++) {
|
||||
if (ImGui::Selectable(dualWSEffects[i-128])) {
|
||||
ins->ws.effect=i;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
const bool isSingleWaveFX=(ins->ws.effect>=128);
|
||||
if (ImGui::BeginTable("WSPreview",isSingleWaveFX?3:2)) {
|
||||
DivWavetable* wave1=e->getWave(ins->ws.wave1);
|
||||
DivWavetable* wave2=e->getWave(ins->ws.wave2);
|
||||
if (wavePreviewInit) {
|
||||
wavePreview.init(ins,wavePreviewLen,wavePreviewHeight,true);
|
||||
wavePreviewInit=false;
|
||||
}
|
||||
float wavePreview1[256];
|
||||
float wavePreview2[256];
|
||||
float wavePreview3[256];
|
||||
for (int i=0; i<wave1->len; i++) {
|
||||
if (wave1->data[i]>wave1->max) {
|
||||
wavePreview1[i]=wave1->max;
|
||||
} else {
|
||||
wavePreview1[i]=wave1->data[i];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<wave2->len; i++) {
|
||||
if (wave2->data[i]>wave2->max) {
|
||||
wavePreview2[i]=wave2->max;
|
||||
} else {
|
||||
wavePreview2[i]=wave2->data[i];
|
||||
}
|
||||
}
|
||||
if (ins->ws.enabled && (!wavePreviewPaused || wavePreviewInit)) {
|
||||
wavePreview.tick(true);
|
||||
}
|
||||
for (int i=0; i<wavePreviewLen; i++) {
|
||||
if (wave2->data[i]>wavePreviewHeight) {
|
||||
wavePreview3[i]=wavePreviewHeight;
|
||||
} else {
|
||||
wavePreview3[i]=wavePreview.output[i];
|
||||
}
|
||||
}
|
||||
|
||||
float ySize=(isSingleWaveFX?96.0f:128.0f)*dpiScale;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 size1=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
|
||||
PlotNoLerp("##WaveformP1",wavePreview1,wave1->len+1,0,"Wave 1",0,wave1->max,size1);
|
||||
if (isSingleWaveFX) {
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 size2=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
|
||||
PlotNoLerp("##WaveformP2",wavePreview2,wave2->len+1,0,"Wave 2",0,wave2->max,size2);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 size3=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
|
||||
PlotNoLerp("##WaveformP3",wavePreview3,wavePreviewLen,0,"Result",0,wavePreviewHeight,size3);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ins->std.waveMacro.len>0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_WARNING]);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Wave 1 " ICON_FA_EXCLAMATION_TRIANGLE);
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("waveform macro is controlling wave 1!\nthis value will be ineffective.");
|
||||
}
|
||||
} else {
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Wave 1");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##SelWave1",&ins->ws.wave1,1,4)) {
|
||||
if (ins->ws.wave1<0) ins->ws.wave1=0;
|
||||
if (ins->ws.wave1>=(int)e->song.wave.size()) ins->ws.wave1=e->song.wave.size()-1;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
if (ins->std.waveMacro.len>0) {
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("waveform macro is controlling wave 1!\nthis value will be ineffective.");
|
||||
}
|
||||
}
|
||||
if (isSingleWaveFX) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Wave 2");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##SelWave2",&ins->ws.wave2,1,4)) {
|
||||
if (ins->ws.wave2<0) ins->ws.wave2=0;
|
||||
if (ins->ws.wave2>=(int)e->song.wave.size()) ins->ws.wave2=e->song.wave.size()-1;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button(wavePreviewPaused?(ICON_FA_PLAY "##WSPause"):(ICON_FA_PAUSE "##WSPause"))) {
|
||||
wavePreviewPaused=!wavePreviewPaused;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (wavePreviewPaused) {
|
||||
ImGui::SetTooltip("Resume preview");
|
||||
} else {
|
||||
ImGui::SetTooltip("Pause preview");
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_REPEAT "##WSRestart")) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Restart preview");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_UPLOAD "##WSCopy")) {
|
||||
curWave=e->addWave();
|
||||
if (curWave==-1) {
|
||||
showError("too many wavetables!");
|
||||
} else {
|
||||
wantScrollList=true;
|
||||
MARK_MODIFIED;
|
||||
RESET_WAVE_MACRO_ZOOM;
|
||||
nextWindow=GUI_WINDOW_WAVE_EDIT;
|
||||
|
||||
DivWavetable* copyWave=e->song.wave[curWave];
|
||||
copyWave->len=wavePreviewLen;
|
||||
copyWave->max=wavePreviewHeight;
|
||||
memcpy(copyWave->data,wavePreview.output,256*sizeof(int));
|
||||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Copy to new wavetable");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("(%d×%d)",wavePreviewLen,wavePreviewHeight+1);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::InputScalar("Update Rate",ImGuiDataType_U8,&ins->ws.rateDivider,&_ONE,&_SEVEN)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
int speed=ins->ws.speed+1;
|
||||
if (ImGui::InputInt("Speed",&speed,1,16)) {
|
||||
if (speed<1) speed=1;
|
||||
if (speed>256) speed=256;
|
||||
ins->ws.speed=speed-1;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
|
||||
if (ImGui::InputScalar("Amount",ImGuiDataType_U8,&ins->ws.param1,&_ONE,&_SEVEN)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
|
||||
if (ins->ws.effect==DIV_WS_PHASE_MOD) {
|
||||
if (ImGui::InputScalar("Power",ImGuiDataType_U8,&ins->ws.param2,&_ONE,&_SEVEN)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Checkbox("Global",&ins->ws.global)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
} else {
|
||||
if ((ins->ws.effect&0x7f)>=DIV_WS_SINGLE_MAX) {
|
||||
ins->ws.effect=0;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginCombo("##WSEffect",(ins->ws.effect&0x80)?dualWSEffects[ins->ws.effect&0x7f]:singleWSEffects[ins->ws.effect&0x7f])) {
|
||||
ImGui::Text("Single-waveform");
|
||||
ImGui::Indent();
|
||||
for (int i=0; i<DIV_WS_SINGLE_MAX; i++) {
|
||||
if (ImGui::Selectable(singleWSEffects[i])) {
|
||||
ins->ws.effect=i;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::Text("Dual-waveform");
|
||||
ImGui::Indent();
|
||||
for (int i=129; i<DIV_WS_DUAL_MAX; i++) {
|
||||
if (ImGui::Selectable(dualWSEffects[i-128])) {
|
||||
ins->ws.effect=i;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
ImGui::Unindent();
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
const bool isSingleWaveFX=(ins->ws.effect>=128);
|
||||
if (ImGui::BeginTable("WSPreview",isSingleWaveFX?3:2)) {
|
||||
DivWavetable* wave1=e->getWave(ins->ws.wave1);
|
||||
DivWavetable* wave2=e->getWave(ins->ws.wave2);
|
||||
if (wavePreviewInit) {
|
||||
wavePreview.init(ins,wavePreviewLen,wavePreviewHeight,true);
|
||||
wavePreviewInit=false;
|
||||
}
|
||||
float wavePreview1[256];
|
||||
float wavePreview2[256];
|
||||
float wavePreview3[256];
|
||||
for (int i=0; i<wave1->len; i++) {
|
||||
if (wave1->data[i]>wave1->max) {
|
||||
wavePreview1[i]=wave1->max;
|
||||
} else {
|
||||
wavePreview1[i]=wave1->data[i];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<wave2->len; i++) {
|
||||
if (wave2->data[i]>wave2->max) {
|
||||
wavePreview2[i]=wave2->max;
|
||||
} else {
|
||||
wavePreview2[i]=wave2->data[i];
|
||||
}
|
||||
}
|
||||
if (ins->ws.enabled && (!wavePreviewPaused || wavePreviewInit)) {
|
||||
wavePreview.tick(true);
|
||||
}
|
||||
for (int i=0; i<wavePreviewLen; i++) {
|
||||
if (wave2->data[i]>wavePreviewHeight) {
|
||||
wavePreview3[i]=wavePreviewHeight;
|
||||
} else {
|
||||
wavePreview3[i]=wavePreview.output[i];
|
||||
}
|
||||
}
|
||||
|
||||
float ySize=(isSingleWaveFX?96.0f:128.0f)*dpiScale;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 size1=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
|
||||
PlotNoLerp("##WaveformP1",wavePreview1,wave1->len+1,0,"Wave 1",0,wave1->max,size1);
|
||||
if (isSingleWaveFX) {
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 size2=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
|
||||
PlotNoLerp("##WaveformP2",wavePreview2,wave2->len+1,0,"Wave 2",0,wave2->max,size2);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 size3=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
|
||||
PlotNoLerp("##WaveformP3",wavePreview3,wavePreviewLen,0,"Result",0,wavePreviewHeight,size3);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Wave 1");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##SelWave1",&ins->ws.wave1,1,4)) {
|
||||
if (ins->ws.wave1<0) ins->ws.wave1=0;
|
||||
if (ins->ws.wave1>=(int)e->song.wave.size()) ins->ws.wave1=e->song.wave.size()-1;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
if (isSingleWaveFX) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Wave 2");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputInt("##SelWave2",&ins->ws.wave2,1,4)) {
|
||||
if (ins->ws.wave2<0) ins->ws.wave2=0;
|
||||
if (ins->ws.wave2>=(int)e->song.wave.size()) ins->ws.wave2=e->song.wave.size()-1;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button(wavePreviewPaused?(ICON_FA_PLAY "##WSPause"):(ICON_FA_PAUSE "##WSPause"))) {
|
||||
wavePreviewPaused=!wavePreviewPaused;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (wavePreviewPaused) {
|
||||
ImGui::SetTooltip("Resume preview");
|
||||
} else {
|
||||
ImGui::SetTooltip("Pause preview");
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_REPEAT "##WSRestart")) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Restart preview");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_UPLOAD "##WSCopy")) {
|
||||
curWave=e->addWave();
|
||||
if (curWave==-1) {
|
||||
showError("too many wavetables!");
|
||||
} else {
|
||||
wantScrollList=true;
|
||||
MARK_MODIFIED;
|
||||
RESET_WAVE_MACRO_ZOOM;
|
||||
nextWindow=GUI_WINDOW_WAVE_EDIT;
|
||||
|
||||
DivWavetable* copyWave=e->song.wave[curWave];
|
||||
copyWave->len=wavePreviewLen;
|
||||
copyWave->max=wavePreviewHeight;
|
||||
memcpy(copyWave->data,wavePreview.output,256*sizeof(int));
|
||||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Copy to new wavetable");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("(%d×%d)",wavePreviewLen,wavePreviewHeight+1);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::InputScalar("Update Rate",ImGuiDataType_U8,&ins->ws.rateDivider,&_ONE,&_SEVEN)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
int speed=ins->ws.speed+1;
|
||||
if (ImGui::InputInt("Speed",&speed,1,16)) {
|
||||
if (speed<1) speed=1;
|
||||
if (speed>256) speed=256;
|
||||
ins->ws.speed=speed-1;
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
|
||||
if (ImGui::InputScalar("Amount",ImGuiDataType_U8,&ins->ws.param1,&_ONE,&_SEVEN)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
|
||||
if (ins->ws.effect==DIV_WS_PHASE_MOD) {
|
||||
if (ImGui::InputScalar("Power",ImGuiDataType_U8,&ins->ws.param2,&_ONE,&_SEVEN)) {
|
||||
wavePreviewInit=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Checkbox("Global",&ins->ws.global)) {
|
||||
wavePreviewInit=true;
|
||||
ImGui::TextWrapped("wavetable synthesizer disabled.\nuse the Waveform macro to set the wave for this instrument.");
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
|
|
|
|||
|
|
@ -800,13 +800,14 @@ void FurnaceGUI::drawPattern() {
|
|||
|
||||
if (e->isRunning()) {
|
||||
DivChannelState* cs=e->getChanState(i);
|
||||
float stereoPan=(float)(e->convertPanSplitToLinearLR(cs->panL,cs->panR,256)-128)/128.0;
|
||||
unsigned short chanPan=e->getChanPan(i);
|
||||
float stereoPan=(float)(e->convertPanSplitToLinear(chanPan,8,256)-128)/128.0;
|
||||
switch (settings.channelVolStyle) {
|
||||
case 1: // simple
|
||||
xRight=((float)(e->getChanState(i)->volume>>8)/(float)e->getMaxVolumeChan(i))*0.9+(keyHit1[i]*0.1f);
|
||||
xRight=((float)(cs->volume>>8)/(float)e->getMaxVolumeChan(i))*0.9+(keyHit1[i]*0.1f);
|
||||
break;
|
||||
case 2: { // stereo
|
||||
float amount=((float)(e->getChanState(i)->volume>>8)/(float)e->getMaxVolumeChan(i))*0.4+(keyHit1[i]*0.1f);
|
||||
float amount=((float)(cs->volume>>8)/(float)e->getMaxVolumeChan(i))*0.4+(keyHit1[i]*0.1f);
|
||||
xRight=0.5+amount*(1.0+MIN(0.0,stereoPan));
|
||||
xLeft=0.5-amount*(1.0-MAX(0.0,stereoPan));
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue