Merge branch 'master' of https://github.com/tildearrow/furnace into nmk112

This commit is contained in:
cam900 2023-10-21 15:15:10 +09:00
commit 15bdb19336
1785 changed files with 523362 additions and 4372 deletions

View file

@ -37,6 +37,14 @@ unsigned short DivDispatch::getPan(int chan) {
return 0;
}
DivChannelPair DivDispatch::getPaired(int chan) {
return DivChannelPair();
}
DivChannelModeHints DivDispatch::getModeHints(int chan) {
return DivChannelModeHints();
}
DivMacroInt* DivDispatch::getChanMacroInt(int chan) {
return NULL;
}
@ -191,6 +199,9 @@ void DivDispatch::renderSamples(int sysID) {
}
void DivDispatch::notifyPitchTable() {
}
int DivDispatch::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
return 0;
}

View file

@ -271,6 +271,14 @@ void DivPlatformC140::tick(bool sysTick) {
}
}
} else {
switch (bankType) {
case 0:
bank=((bank&8)<<2)|(bank&7);
break;
case 1:
bank=((bank&0x18)<<1)|(bank&7);
break;
}
rWrite(0x04+(i<<4),bank);
}
rWrite(0x06+(i<<4),(start>>8)&0xff);
@ -548,7 +556,15 @@ const void* DivPlatformC140::getSampleMem(int index) {
}
size_t DivPlatformC140::getSampleMemCapacity(int index) {
return index == 0 ? (is219?524288:16777216) : 0;
if (index!=0) return 0;
if (is219) return 524288;
switch (bankType) {
case 0:
return 2097152;
case 1:
return 4194304;
}
return 16777216;
}
size_t DivPlatformC140::getSampleMemUsage(int index) {
@ -562,7 +578,7 @@ bool DivPlatformC140::isSampleLoaded(int index, int sample) {
}
void DivPlatformC140::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleMem,0,is219?524288:16777216);
memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
@ -701,6 +717,10 @@ void DivPlatformC140::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/192;
}
bankType=flags.getInt("bankType",0);
if (!is219) {
c140_bank_type(&c140,bankType);
}
for (int i=0; i<totalChans; i++) {
oscBuf[i]->rate=rate;
}
@ -710,12 +730,13 @@ int DivPlatformC140::init(DivEngine* p, int channels, int sugRate, const DivConf
parent=p;
dumpWrites=false;
skipRegisterWrites=false;
bankType=2;
for (int i=0; i<totalChans; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
sampleMem=new unsigned char[getSampleMemCapacity()];
sampleMem=new unsigned char[is219?524288:16777216];
sampleMemLen=0;
if (is219) {
c219_init(&c219);

View file

@ -60,6 +60,7 @@ class DivPlatformC140: public DivDispatch {
bool is219;
int totalChans;
unsigned char groupBank[4];
unsigned char bankType;
unsigned char* sampleMem;
size_t sampleMemLen;

View file

@ -1057,7 +1057,11 @@ DivMacroInt* DivPlatformES5506::getChanMacroInt(int ch) {
}
unsigned short DivPlatformES5506::getPan(int ch) {
return ((chan[ch].lVol>>4)<<8)|(chan[ch].rVol>>4);
float expL=255.0f*pow(((float)(chan[ch].resLVol>>4))/4095.0f,4.0f);
float expR=255.0f*pow(((float)(chan[ch].resRVol>>4))/4095.0f,4.0f);
if (expL>255.0f) expL=255.0f;
if (expR>255.0f) expR=255.0f;
return (((unsigned int)expL)<<8)|((unsigned int)expR);
}
void DivPlatformES5506::reset() {

View file

@ -343,6 +343,10 @@ void DivPlatformNES::tick(bool sysTick) {
} else {
rWrite(0x4010,calcDPCMRate(dacRate)|(goingToLoop?0x40:0));
}
if (nextDPCMDelta>=0) {
rWrite(0x4011,nextDPCMDelta);
nextDPCMDelta=-1;
}
rWrite(0x4012,(dpcmAddr>>6)&0xff);
rWrite(0x4013,dpcmLen&0xff);
rWrite(0x4015,31);
@ -373,11 +377,38 @@ int DivPlatformNES::dispatch(DivCommand c) {
switch (c.cmd) {
case DIV_CMD_NOTE_ON:
if (c.chan==4) { // PCM
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_STD);
if (ins->type==DIV_INS_AMIGA) {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_NES);
if (ins->type==DIV_INS_AMIGA || (ins->type==DIV_INS_NES && !parent->song.oldDPCM)) {
if (ins->type==DIV_INS_NES) {
if (!dpcmMode) {
dpcmMode=true;
if (dumpWrites) addWrite(0xffff0002,0);
dacSample=-1;
rWrite(0x4015,15);
rWrite(0x4010,0);
rWrite(0x4012,0);
rWrite(0x4013,0);
rWrite(0x4015,31);
}
if (ins->amiga.useNoteMap) {
nextDPCMFreq=ins->amiga.getDPCMFreq(c.value);
if (nextDPCMFreq<0 || nextDPCMFreq>15) nextDPCMFreq=lastDPCMFreq;
lastDPCMFreq=nextDPCMFreq;
nextDPCMDelta=ins->amiga.getDPCMDelta(c.value);
} else {
if (c.value==DIV_NOTE_NULL) {
nextDPCMFreq=lastDPCMFreq;
} else {
nextDPCMFreq=c.value&15;
}
}
}
if (c.value!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);
if (ins->type==DIV_INS_AMIGA) {
c.value=ins->amiga.getFreq(c.value);
}
}
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
dacSample=-1;
@ -452,7 +483,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
}
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_NES));
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
}
@ -614,7 +645,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
break;
case DIV_CMD_PRE_PORTA:
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_STD));
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_NES));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
@ -700,6 +731,8 @@ void DivPlatformNES::reset() {
goingToLoop=false;
countMode=false;
nextDPCMFreq=-1;
nextDPCMDelta=-1;
lastDPCMFreq=15;
linearCount=255;
if (useNP) {

View file

@ -54,6 +54,8 @@ class DivPlatformNES: public DivDispatch {
unsigned char apuType;
unsigned char linearCount;
signed char nextDPCMFreq;
signed char nextDPCMDelta;
signed char lastDPCMFreq;
bool dpcmMode;
bool dpcmModeDefault;
bool dacAntiClickOn;

View file

@ -1582,6 +1582,15 @@ unsigned short DivPlatformOPL::getPan(int ch) {
return ((chan[ch].pan&1)<<8)|((chan[ch].pan&2)>>1);
}
DivChannelPair DivPlatformOPL::getPaired(int ch) {
if (oplType==3 && ch<12 && !(ch&1)) {
if (chan[ch].fourOp) {
return DivChannelPair("4OP",ch+1);
}
}
return DivChannelPair();
}
DivDispatchOscBuffer* DivPlatformOPL::getOscBuffer(int ch) {
if (oplType==759 || chipType==8950) {
if (ch>=totalChans+1) return NULL;

View file

@ -115,6 +115,7 @@ class DivPlatformOPL: public DivDispatch {
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
unsigned short getPan(int chan);
DivChannelPair getPaired(int chan);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -406,6 +406,24 @@ DivMacroInt* DivPlatformPOKEY::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivChannelPair DivPlatformPOKEY::getPaired(int ch) {
switch (ch) {
case 0:
if (audctl&4) return DivChannelPair("filter",2);
break;
case 1:
if (audctl&16) return DivChannelPair("16-bit",0);
break;
case 2:
if (audctl&8) return DivChannelPair("16-bit",3);
break;
case 3:
if (audctl&2) return DivChannelPair("filter",1);
break;
}
return DivChannelPair();
}
DivDispatchOscBuffer* DivPlatformPOKEY::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -65,6 +65,7 @@ class DivPlatformPOKEY: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivChannelPair getPaired(int chan);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -472,7 +472,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
break;
case DIV_CMD_SNES_INVERT:
chan[c.chan].invertL=(c.value>>4);
chan[c.chan].invertR=c.chan&15;
chan[c.chan].invertR=c.value&15;
chan[c.chan].shallWriteVol=true;
break;
case DIV_CMD_SNES_GAIN_MODE:
@ -703,6 +703,13 @@ unsigned short DivPlatformSNES::getPan(int ch) {
return (chan[ch].panL<<8)|chan[ch].panR;
}
DivChannelPair DivPlatformSNES::getPaired(int ch) {
if (chan[ch].pitchMod) {
return DivChannelPair("mod",(ch-1)&7);
}
return DivChannelPair();
}
DivSamplePos DivPlatformSNES::getSamplePos(int ch) {
if (ch>=8) return DivSamplePos();
if (!chan[ch].active) return DivSamplePos();

View file

@ -101,6 +101,7 @@ class DivPlatformSNES: public DivDispatch {
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
unsigned short getPan(int chan);
DivChannelPair getPaired(int chan);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();

View file

@ -333,6 +333,11 @@ void c219_reset(struct c219_t *c219)
}
}
// TILDEARROW
void c140_bank_type(struct c140_t *c140, unsigned char type) {
c140->bank_type = type;
}
void c140_write(struct c140_t *c140, const unsigned short addr, const unsigned char data)
{
// voice register
@ -345,7 +350,16 @@ void c140_write(struct c140_t *c140, const unsigned short addr, const unsigned c
case 0x1: voice->lvol = data; break;
case 0x2: voice->freq = (voice->freq & ~0xff00) | (unsigned int)(data << 8); break;
case 0x3: voice->freq = (voice->freq & ~0x00ff) | data; break;
case 0x4: voice->bank = data; break;
case 0x4: { // TILDEARROW
if (c140->bank_type == 0) {
voice->bank = ((data&0x20)>>2)|(data&7);
} else if (c140->bank_type == 1) {
voice->bank = ((data&0x30)>>1)|(data&7);
} else {
voice->bank = data;
}
break;
}
case 0x5:
voice->compressed = c140_bit(data, 3);
voice->loop = c140_bit(data, 4);

View file

@ -5,7 +5,7 @@
MODIFIED Namco C140/C219 sound emulator - MODIFIED VERSION
by cam900
MODIFICATION by tildearrow - adds muting function
MODIFICATION by tildearrow - adds muting function AND VGM banking
THIS IS NOT THE ORIGINAL VERSION - you can find the original one in
commit 72d04777c013988ed8cf6da27c62a9d784a59dff
@ -78,6 +78,7 @@ struct c140_t
signed int lout, rout;
signed short mulaw[256];
signed short *sample_mem;
unsigned char bank_type;
};
struct c219_t
@ -106,6 +107,8 @@ void c140_write(struct c140_t *c140, const unsigned short addr, const unsigned c
void c219_write(struct c219_t *c219, const unsigned short addr, const unsigned char data);
void c140_bank_type(struct c140_t *c140, unsigned char type);
void c140_init(struct c140_t *c140);
void c219_init(struct c219_t *c219);

View file

@ -447,6 +447,7 @@ void DivPlatformSoundUnit::forceIns() {
chWrite(i,0x03,chan[i].pan);
writeControl(i);
writeControlUpper(i);
chWrite(i,0x08,chan[i].duty);
}
}