ADSFGGGGGJKSDGHASLJKFHL

This commit is contained in:
tildearrow 2022-09-24 19:40:03 -05:00
parent 2c7abb4635
commit a0dc9de262
4 changed files with 72 additions and 38 deletions

View File

@ -94,12 +94,15 @@ void DivPlatformSNES::tick(bool sysTick) {
unsigned char kon=0; unsigned char kon=0;
unsigned char koff=0; unsigned char koff=0;
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA); //bool hadGain=chan[i].std.vol.had || chan[i].std.ex1.had || chan[i].std.ex2.had;
bool hadGain=chan[i].std.vol.had || chan[i].std.ex1.had || chan[i].std.ex2.had;
chan[i].std.next(); chan[i].std.next();
if (ins->type==DIV_INS_AMIGA && chan[i].std.vol.had) { if (chan[i].std.vol.had) {
chan[i].outVol=VOL_SCALE_LOG(chan[i].vol&127,MIN(127,chan[i].std.vol.val),127);
}
/*
if (chan[i].std.vol.had) {
chWrite(i,7,MIN(127,chan[i].std.vol.val*2)); chWrite(i,7,MIN(127,chan[i].std.vol.val*2));
} else if (!chan[i].useEnv && hadGain) { } else if (!chan[i].state.useEnv && hadGain) {
if (chan[i].std.ex1.val==0) { if (chan[i].std.ex1.val==0) {
// direct gain // direct gain
chWrite(i,7,chan[i].std.vol.val); chWrite(i,7,chan[i].std.vol.val);
@ -107,7 +110,7 @@ void DivPlatformSNES::tick(bool sysTick) {
// inc/dec // inc/dec
chWrite(i,7,chan[i].std.ex2.val|((chan[i].std.ex1.val-1)<<5)|0x80); chWrite(i,7,chan[i].std.ex2.val|((chan[i].std.ex1.val-1)<<5)|0x80);
} }
} }*/
if (chan[i].std.arp.had) { if (chan[i].std.arp.had) {
if (!chan[i].inPorta) { if (!chan[i].inPorta) {
if (chan[i].std.arp.mode) { if (chan[i].std.arp.mode) {
@ -146,7 +149,7 @@ void DivPlatformSNES::tick(bool sysTick) {
int val=chan[i].std.panR.val&0x7f; int val=chan[i].std.panR.val&0x7f;
chan[i].panR=(val<<1)|(val>>6); chan[i].panR=(val<<1)|(val>>6);
} }
if (chan[i].std.panL.had || chan[i].std.panR.had) { if (chan[i].std.vol.had || chan[i].std.panL.had || chan[i].std.panR.had) {
writeOutVol(i); writeOutVol(i);
} }
if (chan[i].setPos) { if (chan[i].setPos) {
@ -168,12 +171,29 @@ void DivPlatformSNES::tick(bool sysTick) {
if (chan[i].freq>16383) chan[i].freq=16383; if (chan[i].freq>16383) chan[i].freq=16383;
if (chan[i].keyOn) { if (chan[i].keyOn) {
unsigned int start, end, loop; unsigned int start, end, loop;
size_t tabAddr=sampleTableAddr(i); unsigned short tabAddr=sampleTableAddr(i);
if (chan[i].useEnv) { if (chan[i].state.useEnv) {
chWrite(i,5,ins->snes.a|(ins->snes.d<<4)|0x80); chWrite(i,5,chan[i].state.a|(chan[i].state.d<<4)|0x80);
chWrite(i,6,ins->snes.r|(ins->snes.s<<5)); chWrite(i,6,chan[i].state.r|(chan[i].state.s<<5));
} else { } else {
chWrite(i,5,0); chWrite(i,5,0);
switch (chan[i].state.gainMode) {
case DivInstrumentSNES::GAIN_MODE_DIRECT:
chWrite(i,7,chan[i].state.gain&127);
break;
case DivInstrumentSNES::GAIN_MODE_DEC_LINEAR:
chWrite(i,7,0x80|(chan[i].state.gain&31));
break;
case DivInstrumentSNES::GAIN_MODE_INC_LINEAR:
chWrite(i,7,0xc0|(chan[i].state.gain&31));
break;
case DivInstrumentSNES::GAIN_MODE_DEC_LOG:
chWrite(i,7,0xa0|(chan[i].state.gain&31));
break;
case DivInstrumentSNES::GAIN_MODE_INC_INVLOG:
chWrite(i,7,0xe0|(chan[i].state.gain&31));
break;
}
} }
if (chan[i].useWave) { if (chan[i].useWave) {
start=waveTableAddr(i); start=waveTableAddr(i);
@ -193,9 +213,6 @@ void DivPlatformSNES::tick(bool sysTick) {
sampleMem[tabAddr+1]=start>>8; sampleMem[tabAddr+1]=start>>8;
sampleMem[tabAddr+2]=loop&0xff; sampleMem[tabAddr+2]=loop&0xff;
sampleMem[tabAddr+3]=loop>>8; sampleMem[tabAddr+3]=loop>>8;
if (!hadGain) {
chWrite(i,7,0x7f);
}
kon|=(1<<i); kon|=(1<<i);
chan[i].keyOn=false; chan[i].keyOn=false;
} }
@ -220,7 +237,7 @@ void DivPlatformSNES::tick(bool sysTick) {
int DivPlatformSNES::dispatch(DivCommand c) { int DivPlatformSNES::dispatch(DivCommand c) {
switch (c.cmd) { switch (c.cmd) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_SNES);
if (ins->amiga.useWave) { if (ins->amiga.useWave) {
chan[c.chan].useWave=true; chan[c.chan].useWave=true;
chan[c.chan].wtLen=ins->amiga.waveLen+1; chan[c.chan].wtLen=ins->amiga.waveLen+1;
@ -239,6 +256,9 @@ int DivPlatformSNES::dispatch(DivCommand c) {
if (chan[c.chan].useWave || chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) { if (chan[c.chan].useWave || chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) {
chan[c.chan].sample=-1; chan[c.chan].sample=-1;
} }
if (chan[c.chan].insChanged) {
chan[c.chan].state=ins->snes;
}
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value)); chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value));
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
@ -247,11 +267,6 @@ int DivPlatformSNES::dispatch(DivCommand c) {
chan[c.chan].active=true; chan[c.chan].active=true;
chan[c.chan].keyOn=true; chan[c.chan].keyOn=true;
chan[c.chan].macroInit(ins); chan[c.chan].macroInit(ins);
if (ins->type==DIV_INS_SNES) {
// initialize to max gain in case of direct gain mode macro without gain level macro
chan[c.chan].std.vol.val=0x7f;
chan[c.chan].useEnv=ins->snes.useEnv;
}
chan[c.chan].insChanged=false; chan[c.chan].insChanged=false;
break; break;
} }
@ -277,12 +292,6 @@ int DivPlatformSNES::dispatch(DivCommand c) {
writeOutVol(c.chan); writeOutVol(c.chan);
} }
break; break;
// case DIV_CMD_GLOBAL_VOLUME:
// gblVolL=MIN(c.value,127);
// gblVolR=MIN(c.value,127);
// rWrite(0x0c,gblVolL);
// rWrite(0x1c,gblVolR);
// break;
case DIV_CMD_GET_VOLUME: case DIV_CMD_GET_VOLUME:
return chan[c.chan].vol; return chan[c.chan].vol;
break; break;
@ -326,7 +335,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
} }
case DIV_CMD_PRE_PORTA: case DIV_CMD_PRE_PORTA:
if (chan[c.chan].active && c.value2) { if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA)); if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SNES));
} }
chan[c.chan].inPorta=c.value; chan[c.chan].inPorta=c.value;
break; break;
@ -346,7 +355,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
void DivPlatformSNES::updateWave(int ch) { void DivPlatformSNES::updateWave(int ch) {
// Due to the overflow bug in hardware's resampler, the written amplitude here is half of maximum // Due to the overflow bug in hardware's resampler, the written amplitude here is half of maximum
size_t pos=waveTableAddr(ch); unsigned short pos=waveTableAddr(ch);
for (int i=0; i<chan[ch].wtLen/16; i++) { for (int i=0; i<chan[ch].wtLen/16; i++) {
sampleMem[pos++]=0xb0; sampleMem[pos++]=0xb0;
for (int j=0; j<8; j++) { for (int j=0; j<8; j++) {
@ -363,8 +372,8 @@ void DivPlatformSNES::writeOutVol(int ch) {
int outL=0; int outL=0;
int outR=0; int outR=0;
if (!isMuted[ch]) { if (!isMuted[ch]) {
outL=chan[ch].vol*chan[ch].panL/255; outL=(globalVolL*((chan[ch].outVol*chan[ch].panL)/127))/127;
outR=chan[ch].vol*chan[ch].panR/255; outR=(globalVolR*((chan[ch].outVol*chan[ch].panR)/127))/127;
} }
chWrite(ch,0,outL); chWrite(ch,0,outL);
chWrite(ch,1,outR); chWrite(ch,1,outR);
@ -417,6 +426,7 @@ void DivPlatformSNES::reset() {
// TODO more initial values // TODO more initial values
// this can't be 0 or channel 1 won't play // this can't be 0 or channel 1 won't play
// this can't be 0x100 either as that's used by SPC700 page 1 and the stack // this can't be 0x100 either as that's used by SPC700 page 1 and the stack
// this may not even be 0x200 as some space will be taken by the playback routine and variables
sampleTableBase=0x200; sampleTableBase=0x200;
rWrite(0x5d,sampleTableBase>>8); rWrite(0x5d,sampleTableBase>>8);
rWrite(0x0c,127); // global volume left rWrite(0x0c,127); // global volume left
@ -506,6 +516,11 @@ void DivPlatformSNES::renderSamples() {
sampleMemLen=memPos; sampleMemLen=memPos;
} }
void DivPlatformSNES::setFlags(unsigned int flags) {
globalVolL=127-(flags&127);
globalVolR=127-((flags>>8)&127);
}
int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
parent=p; parent=p;
dumpWrites=false; dumpWrites=false;
@ -517,6 +532,7 @@ int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, unsigned int
sampleMemLen=0; sampleMemLen=0;
chipClock=1024000; chipClock=1024000;
rate=chipClock/32; rate=chipClock/32;
setFlags(flags);
reset(); reset();
return 8; return 8;
} }

View File

@ -34,9 +34,9 @@ class DivPlatformSNES: public DivDispatch {
int note; int note;
int panL, panR; int panL, panR;
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos; bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos;
signed char vol; int vol, outVol;
int wtLen; int wtLen;
bool useEnv; DivInstrumentSNES state;
DivMacroInt std; DivMacroInt std;
DivWaveSynth ws; DivWaveSynth ws;
void macroInit(DivInstrument* which) { void macroInit(DivInstrument* which) {
@ -53,8 +53,8 @@ class DivPlatformSNES: public DivDispatch {
wave(-1), wave(-1),
ins(-1), ins(-1),
note(0), note(0),
panL(255), panL(127),
panR(255), panR(127),
active(false), active(false),
insChanged(true), insChanged(true),
freqChanged(false), freqChanged(false),
@ -64,13 +64,13 @@ class DivPlatformSNES: public DivDispatch {
useWave(false), useWave(false),
setPos(false), setPos(false),
vol(127), vol(127),
wtLen(16), outVol(127),
useEnv(false) {} wtLen(16) {}
}; };
Channel chan[8]; Channel chan[8];
DivDispatchOscBuffer* oscBuf[8]; DivDispatchOscBuffer* oscBuf[8];
bool isMuted[8]; bool isMuted[8];
signed char gblVolL, gblVolR; signed char globalVolL, globalVolR;
size_t sampleTableBase; size_t sampleTableBase;
struct QueuedWrite { struct QueuedWrite {
@ -101,6 +101,7 @@ class DivPlatformSNES: public DivDispatch {
bool isStereo(); bool isStereo();
void notifyInsChange(int ins); void notifyInsChange(int ins);
void notifyWaveChange(int wave); void notifyWaveChange(int wave);
void setFlags(unsigned int flags);
void notifyInsDeletion(void* ins); void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val); void poke(unsigned int addr, unsigned short val);
void poke(std::vector<DivRegWrite>& wlist); void poke(std::vector<DivRegWrite>& wlist);

View File

@ -4295,7 +4295,9 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_AMIGA) {
volMax=64; volMax=64;
} }
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_MIKEY || ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_SU || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { if (ins->type==DIV_INS_FM || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_MIKEY ||
ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_SU || ins->type==DIV_INS_OPZ ||
ins->type==DIV_INS_OPM || ins->type==DIV_INS_SNES) {
volMax=127; volMax=127;
} }
if (ins->type==DIV_INS_GB) { if (ins->type==DIV_INS_GB) {

View File

@ -755,12 +755,27 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
} }
break; break;
} }
case DIV_SYSTEM_SNES: {
ImGui::Text("Volume scale:");
int vsL=127-(flags&127);
int vsR=127-((flags>>8)&127);
if (CWSliderInt("Left##VolScaleL",&vsL,0,127)) {
if (vsL<0) vsL=0;
if (vsL>127) vsL=127;
copyOfFlags=(flags&(~0x7f))|(127-vsL);
} rightClickable
if (CWSliderInt("Right##VolScaleL",&vsR,0,127)) {
if (vsR<0) vsR=0;
if (vsR>127) vsR=127;
copyOfFlags=(flags&(~0x7f00))|((127-vsR)<<8);
} rightClickable
break;
}
case DIV_SYSTEM_SWAN: case DIV_SYSTEM_SWAN:
case DIV_SYSTEM_VERA: case DIV_SYSTEM_VERA:
case DIV_SYSTEM_BUBSYS_WSG: case DIV_SYSTEM_BUBSYS_WSG:
case DIV_SYSTEM_YMU759: case DIV_SYSTEM_YMU759:
case DIV_SYSTEM_PET: case DIV_SYSTEM_PET:
case DIV_SYSTEM_SNES:
case DIV_SYSTEM_T6W28: case DIV_SYSTEM_T6W28:
ImGui::Text("nothing to configure"); ImGui::Text("nothing to configure");
break; break;