Merge branch 'tildearrow:master' into master

This commit is contained in:
DevEd 2022-03-03 18:52:04 -05:00 committed by GitHub
commit c6c992482e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 135 additions and 104 deletions

BIN
demos/Coconut_Mall.fur Normal file

Binary file not shown.

View file

@ -119,13 +119,13 @@ size | description
| - 0x06: NES - 5 channels | - 0x06: NES - 5 channels
| - 0x07: C64 (8580) - 3 channels | - 0x07: C64 (8580) - 3 channels
| - 0x08: Arcade (YM2151+SegaPCM) - 13 channels (compound!) | - 0x08: Arcade (YM2151+SegaPCM) - 13 channels (compound!)
| - 0x09: Neo Geo (YM2610) - 13 channels | - 0x09: Neo Geo CD (YM2610) - 13 channels
| - bit 6 enables alternate mode: | - bit 6 enables alternate mode:
| - 0x42: Genesis extended - 13 channels | - 0x42: Genesis extended - 13 channels
| - 0x43: SMS (SN76489) + OPLL (YM2413) - 13 channels (compound!) | - 0x43: SMS (SN76489) + OPLL (YM2413) - 13 channels (compound!)
| - 0x46: NES + VRC7 - 11 channels (compound!) | - 0x46: NES + VRC7 - 11 channels (compound!)
| - 0x47: C64 (6581) - 3 channels | - 0x47: C64 (6581) - 3 channels
| - 0x49: Neo Geo extended - 16 channels | - 0x49: Neo Geo CD extended - 16 channels
| - bit 7 for non-DefleMask chips: | - bit 7 for non-DefleMask chips:
| - 0x80: AY-3-8910 - 3 channels | - 0x80: AY-3-8910 - 3 channels
| - 0x81: Amiga - 4 channels | - 0x81: Amiga - 4 channels
@ -164,10 +164,13 @@ size | description
| - 0xa2: OPL drums (YM3526) - 11 channels | - 0xa2: OPL drums (YM3526) - 11 channels
| - 0xa3: OPL2 drums (YM3812) - 11 channels | - 0xa3: OPL2 drums (YM3812) - 11 channels
| - 0xa4: OPL3 drums (YMF262) - 20 channels | - 0xa4: OPL3 drums (YMF262) - 20 channels
| - 0xa5: OPL3 4-op (YMF262) - 12 channels | - 0xa5: Neo Geo (YM2610) - 14 channels
| - 0xa6: OPL3 4-op + drums (YMF262) - 14 channels | - 0xa6: Neo Geo extended (YM2610) - 17 channels
| - 0xa7: OPLL drums (YM2413) - 11 channels | - 0xa7: OPLL drums (YM2413) - 11 channels
| - 0xa8: Atari Lynx - 4 channels | - 0xa8: Atari Lynx - 4 channels
| - 0xa9: SegaPCM (for Deflemask Compatibility) - 5 channels
| - 0xaa: MSM6295 - 4 channels
| - 0xab: MSM6258 - 1 channel
| - 0xde: YM2610B extended - 19 channels | - 0xde: YM2610B extended - 19 channels
| - 0xe0: QSound - 19 channels | - 0xe0: QSound - 19 channels
| - (compound!) means that the system is composed of two or more chips, | - (compound!) means that the system is composed of two or more chips,

View file

@ -17,4 +17,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "../../extern/rtmidi/RtMidi.h" #include "../../extern/rtmidi/RtMidi.h"
#include "taAudio.h"
class TAMidiInRtMidi: public TAMidiIn {
};
class TAMidiOutRtMidi: public TAMidiOut {
};

View file

@ -20,6 +20,7 @@
#ifndef _TAAUDIO_H #ifndef _TAAUDIO_H
#define _TAAUDIO_H #define _TAAUDIO_H
#include "../ta-utils.h" #include "../ta-utils.h"
#include <queue>
#include <vector> #include <vector>
struct SampleRateChangeEvent { struct SampleRateChangeEvent {
@ -116,14 +117,24 @@ struct TAMidiMessage {
void submitSysEx(std::vector<unsigned char> data); void submitSysEx(std::vector<unsigned char> data);
void done(); void done();
TAMidiMessage():
type(0),
sysExData(NULL),
sysExLen(0) {
memset(&data,0,sizeof(data));
}
}; };
class TAMidiIn { class TAMidiIn {
std::queue<TAMidiMessage> queue;
public: public:
virtual bool gather();
bool next(TAMidiMessage& where); bool next(TAMidiMessage& where);
}; };
class TAMidiOut { class TAMidiOut {
std::queue<TAMidiMessage> queue;
public: public:
bool send(TAMidiMessage& what); bool send(TAMidiMessage& what);
}; };
@ -140,8 +151,8 @@ class TAAudio {
void (*sampleRateChanged)(SampleRateChangeEvent); void (*sampleRateChanged)(SampleRateChangeEvent);
void (*bufferSizeChanged)(BufferSizeChangeEvent); void (*bufferSizeChanged)(BufferSizeChangeEvent);
public: public:
std::vector<TAMidiIn*> midiIn; TAMidiIn* midiIn;
std::vector<TAMidiOut*> midiOut; TAMidiOut* midiOut;
void setSampleRateChangeCallback(void (*callback)(SampleRateChangeEvent)); void setSampleRateChangeCallback(void (*callback)(SampleRateChangeEvent));
void setBufferSizeChangeCallback(void (*callback)(BufferSizeChangeEvent)); void setBufferSizeChangeCallback(void (*callback)(BufferSizeChangeEvent));

View file

@ -133,17 +133,11 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s
//OPN2_Write(&fm,0,0); //OPN2_Write(&fm,0,0);
} }
psgClocks+=psg.rate; os[0]=(os[0]<<5);
while (psgClocks>=rate) {
psgOut=(psg.acquireOne()*3)>>3;
psgClocks-=rate;
}
os[0]=(os[0]<<5)+psgOut;
if (os[0]<-32768) os[0]=-32768; if (os[0]<-32768) os[0]=-32768;
if (os[0]>32767) os[0]=32767; if (os[0]>32767) os[0]=32767;
os[1]=(os[1]<<5)+psgOut; os[1]=(os[1]<<5);
if (os[1]<-32768) os[1]=-32768; if (os[1]<-32768) os[1]=-32768;
if (os[1]>32767) os[1]=32767; if (os[1]>32767) os[1]=32767;
@ -197,17 +191,9 @@ void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, si
os[1]=out_ymfm.data[1]; os[1]=out_ymfm.data[1];
//OPN2_Write(&fm,0,0); //OPN2_Write(&fm,0,0);
psgClocks+=psg.rate;
while (psgClocks>=rate) {
psgOut=(psg.acquireOne()*3)>>3;
psgClocks-=rate;
}
os[0]=os[0]+psgOut;
if (os[0]<-32768) os[0]=-32768; if (os[0]<-32768) os[0]=-32768;
if (os[0]>32767) os[0]=32767; if (os[0]>32767) os[0]=32767;
os[1]=os[1]+psgOut;
if (os[1]<-32768) os[1]=-32768; if (os[1]<-32768) os[1]=-32768;
if (os[1]>32767) os[1]=32767; if (os[1]>32767) os[1]=32767;
@ -391,13 +377,6 @@ void DivPlatformGenesis::tick() {
chan[i].keyOn=false; chan[i].keyOn=false;
} }
} }
psg.tick();
for (DivRegWrite& i: psg.getRegisterWrites()) {
if (dumpWrites) addWrite(i.addr,i.val);
}
psg.getRegisterWrites().clear();
} }
int DivPlatformGenesis::octave(int freq) { int DivPlatformGenesis::octave(int freq) {
@ -442,10 +421,6 @@ int DivPlatformGenesis::toFreq(int freq) {
} }
void DivPlatformGenesis::muteChannel(int ch, bool mute) { void DivPlatformGenesis::muteChannel(int ch, bool mute) {
if (ch>5) {
psg.muteChannel(ch-6,mute);
return;
}
isMuted[ch]=mute; isMuted[ch]=mute;
for (int j=0; j<4; j++) { for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[ch]|opOffs[j]; unsigned short baseAddr=chanOffs[ch]|opOffs[j];
@ -464,10 +439,6 @@ void DivPlatformGenesis::muteChannel(int ch, bool mute) {
} }
int DivPlatformGenesis::dispatch(DivCommand c) { int DivPlatformGenesis::dispatch(DivCommand c) {
if (c.chan>5) {
c.chan-=6;
return psg.dispatch(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); DivInstrument* ins=parent->getIns(chan[c.chan].ins);
@ -786,16 +757,13 @@ void DivPlatformGenesis::forceIns() {
rWrite(0x2b,0x80); rWrite(0x2b,0x80);
} }
immWrite(0x22,lfoValue); immWrite(0x22,lfoValue);
psg.forceIns();
} }
void DivPlatformGenesis::toggleRegisterDump(bool enable) { void DivPlatformGenesis::toggleRegisterDump(bool enable) {
DivDispatch::toggleRegisterDump(enable); DivDispatch::toggleRegisterDump(enable);
psg.toggleRegisterDump(enable);
} }
void* DivPlatformGenesis::getChanState(int ch) { void* DivPlatformGenesis::getChanState(int ch) {
if (ch>5) return psg.getChanState(ch-6);
return &chan[ch]; return &chan[ch];
} }
@ -844,12 +812,6 @@ void DivPlatformGenesis::reset() {
immWrite(0x22,lfoValue); immWrite(0x22,lfoValue);
delay=0; delay=0;
// PSG
psg.reset();
psg.getRegisterWrites().clear();
psgClocks=0;
psgOut=0;
} }
bool DivPlatformGenesis::isStereo() { bool DivPlatformGenesis::isStereo() {
@ -865,17 +827,14 @@ bool DivPlatformGenesis::keyOffAffectsPorta(int ch) {
} }
void DivPlatformGenesis::notifyInsChange(int ins) { void DivPlatformGenesis::notifyInsChange(int ins) {
for (int i=0; i<10; i++) { for (int i=0; i<6; i++) {
if (i>5) { if (chan[i].ins==ins) {
psg.notifyInsChange(ins);
} else if (chan[i].ins==ins) {
chan[i].insChanged=true; chan[i].insChanged=true;
} }
} }
} }
void DivPlatformGenesis::notifyInsDeletion(void* ins) { void DivPlatformGenesis::notifyInsDeletion(void* ins) {
psg.notifyInsDeletion(ins);
} }
void DivPlatformGenesis::poke(unsigned int addr, unsigned short val) { void DivPlatformGenesis::poke(unsigned int addr, unsigned short val) {
@ -904,7 +863,6 @@ void DivPlatformGenesis::setFlags(unsigned int flags) {
} else { } else {
chipClock=COLOR_NTSC*15.0/7.0; chipClock=COLOR_NTSC*15.0/7.0;
} }
psg.setFlags(flags==1);
ladder=flags&0x80000000; ladder=flags&0x80000000;
OPN2_SetChipType(ladder?ym3438_mode_ym2612:0); OPN2_SetChipType(ladder?ym3438_mode_ym2612:0);
if (useYMFM) { if (useYMFM) {
@ -929,7 +887,6 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i
isMuted[i]=false; isMuted[i]=false;
} }
fm_ymfm=NULL; fm_ymfm=NULL;
psg.init(p,4,sugRate,flags==1);
setFlags(flags); setFlags(flags);
reset(); reset();
@ -938,7 +895,6 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i
void DivPlatformGenesis::quit() { void DivPlatformGenesis::quit() {
if (fm_ymfm!=NULL) delete fm_ymfm; if (fm_ymfm!=NULL) delete fm_ymfm;
psg.quit();
} }
DivPlatformGenesis::~DivPlatformGenesis() { DivPlatformGenesis::~DivPlatformGenesis() {

View file

@ -70,9 +70,6 @@ class DivPlatformGenesis: public DivDispatch {
}; };
std::queue<QueuedWrite> writes; std::queue<QueuedWrite> writes;
ym3438_t fm; ym3438_t fm;
DivPlatformSMS psg;
int psgClocks;
int psgOut;
int delay; int delay;
unsigned char lastBusy; unsigned char lastBusy;

View file

@ -133,7 +133,9 @@ void DivPlatformOPLL::tick() {
if (chan[i].std.hadVol) { if (chan[i].std.hadVol) {
chan[i].outVol=(chan[i].vol*MIN(15,chan[i].std.vol))/15; chan[i].outVol=(chan[i].vol*MIN(15,chan[i].std.vol))/15;
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); if (i<9) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4));
}
} }
if (chan[i].std.hadArp) { if (chan[i].std.hadArp) {
@ -159,15 +161,15 @@ void DivPlatformOPLL::tick() {
} }
if (chan[i].std.hadFb) { if (chan[i].std.hadFb) {
chan[i].state.fb=chan[i].std.fb; chan[i].state.fb=chan[i].std.fb;
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
} }
if (chan[i].std.hadFms) { if (chan[i].std.hadFms) {
chan[i].state.fms=chan[i].std.fms; chan[i].state.fms=chan[i].std.fms;
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
} }
if (chan[i].std.hadAms) { if (chan[i].std.hadAms) {
chan[i].state.ams=chan[i].std.ams; chan[i].state.ams=chan[i].std.ams;
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
} }
for (int j=0; j<2; j++) { for (int j=0; j<2; j++) {
@ -201,9 +203,11 @@ void DivPlatformOPLL::tick() {
if (m.hadTl) { if (m.hadTl) {
op.tl=((j==1)?15:63)-m.tl; op.tl=((j==1)?15:63)-m.tl;
if (j==1) { if (j==1) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); if (i<9) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4));
}
} else { } else {
rWrite(0x02,(chan[i].state.op[1].ksl<<6)|(op.tl&63)); rWrite(0x02,(chan[i].state.op[0].ksl<<6)|(op.tl&63));
} }
} }
@ -214,9 +218,9 @@ void DivPlatformOPLL::tick() {
if (m.hadKsl) { if (m.hadKsl) {
op.ksl=m.ksl; op.ksl=m.ksl;
if (j==1) { if (j==1) {
rWrite(0x02,(op.ksl<<6)|(chan[i].state.op[0].tl&63)); rWrite(0x02,(chan[i].state.op[0].ksl<<6)|(chan[i].state.op[0].tl&63));
} else { } else {
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
} }
} }
if (m.hadKsr) { if (m.hadKsr) {
@ -238,7 +242,9 @@ void DivPlatformOPLL::tick() {
drumState&=~(0x10>>(chan[i].note%12)); drumState&=~(0x10>>(chan[i].note%12));
immWrite(0x0e,0x20|drumState); immWrite(0x0e,0x20|drumState);
} else { } else {
immWrite(0x20+i,(chan[i].freqH)/*|(chan[i].state.alg?0x20:0)*/); if (i<9) {
immWrite(0x20+i,(chan[i].freqH)|(chan[i].state.alg?0x20:0));
}
} }
//chan[i].keyOn=false; //chan[i].keyOn=false;
chan[i].keyOff=false; chan[i].keyOff=false;
@ -257,21 +263,23 @@ void DivPlatformOPLL::tick() {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq)); chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,octave(chan[i].baseFreq));
if (chan[i].freq>262143) chan[i].freq=262143; if (chan[i].freq>262143) chan[i].freq=262143;
int freqt=toFreq(chan[i].freq); int freqt=toFreq(chan[i].freq);
chan[i].freqH=freqt>>8;
chan[i].freqL=freqt&0xff; chan[i].freqL=freqt&0xff;
if (i>=6 && properDrums) { if (i>=6 && properDrums) {
immWrite(0x10+drumSlot[i],freqt&0xff); immWrite(0x10+drumSlot[i],freqt&0xff);
immWrite(0x20+drumSlot[i],freqt>>8); immWrite(0x20+drumSlot[i],freqt>>8);
} else if (i<6 || !drums) { } else if (i<6 || !drums) {
immWrite(0x10+i,freqt&0xff); if (i<9) {
immWrite(0x10+i,freqt&0xff);
}
} }
chan[i].freqH=freqt>>8;
} }
if (chan[i].keyOn && i>=6 && properDrums) { if (chan[i].keyOn && i>=6 && properDrums) {
if (!isMuted[i]) { if (!isMuted[i]) {
drumState|=(0x10>>(i-6)); drumState|=(0x10>>(i-6));
immWrite(0x0e,0x20|drumState); immWrite(0x0e,0x20|drumState);
} }
chan[i].keyOn=false; chan[i].keyOn=false;
} else if (chan[i].keyOn && i>=6 && drums) { } else if (chan[i].keyOn && i>=6 && drums) {
//printf("%d\n",chan[i].note%12); //printf("%d\n",chan[i].note%12);
drumState|=(0x10>>(chan[i].note%12)); drumState|=(0x10>>(chan[i].note%12));
@ -279,7 +287,11 @@ void DivPlatformOPLL::tick() {
chan[i].keyOn=false; chan[i].keyOn=false;
} else if ((chan[i].keyOn || chan[i].freqChanged) && i<9) { } else if ((chan[i].keyOn || chan[i].freqChanged) && i<9) {
//immWrite(0x28,0xf0|konOffs[i]); //immWrite(0x28,0xf0|konOffs[i]);
immWrite(0x20+i,(chan[i].freqH)|(chan[i].active<<4)|(chan[i].state.alg?0x20:0)); if (!(i>=6 && properDrums)) {
if (i<9) {
immWrite(0x20+i,(chan[i].freqH)|(chan[i].active<<4)|(chan[i].state.alg?0x20:0));
}
}
chan[i].keyOn=false; chan[i].keyOn=false;
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
@ -381,8 +393,8 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult)); rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult)); rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
rWrite(0x02,(car.ksl<<6)|(mod.tl&63)); rWrite(0x02,(mod.ksl<<6)|(mod.tl&63));
rWrite(0x03,(mod.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb); rWrite(0x03,(car.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb);
rWrite(0x04,(mod.ar<<4)|(mod.dr)); rWrite(0x04,(mod.ar<<4)|(mod.dr));
rWrite(0x05,(car.ar<<4)|(car.dr)); rWrite(0x05,(car.ar<<4)|(car.dr));
rWrite(0x06,(mod.sl<<4)|(mod.rr)); rWrite(0x06,(mod.sl<<4)|(mod.rr));
@ -410,7 +422,9 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
immWrite(0x0e,0); immWrite(0x0e,0);
} }
} }
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4)); if (c.chan<9) {
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4));
}
} }
} }
@ -477,9 +491,10 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
rWrite(0x37,drumVol[1]|(drumVol[4]<<4)); rWrite(0x37,drumVol[1]|(drumVol[4]<<4));
rWrite(0x38,drumVol[3]|(drumVol[2]<<4)); rWrite(0x38,drumVol[3]|(drumVol[2]<<4));
break; break;
} } else if (c.chan<6 || !drums) {
if (c.chan<6 || !drums) { if (c.chan<9) {
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4)); rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4));
}
} }
break; break;
} }
@ -541,10 +556,10 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
} }
case DIV_CMD_FM_FB: { case DIV_CMD_FM_FB: {
if (c.chan>=9 && !properDrums) return 0; if (c.chan>=9 && !properDrums) return 0;
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; //DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
//DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
chan[c.chan].state.fb=c.value&7; chan[c.chan].state.fb=c.value&7;
rWrite(0x03,(mod.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb); rWrite(0x03,(car.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb);
break; break;
} }
@ -565,13 +580,15 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
if (c.chan>=9 && !properDrums) return 0; if (c.chan>=9 && !properDrums) return 0;
if (c.value==0) { if (c.value==0) {
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; //DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
mod.tl=c.value2&63; mod.tl=c.value2&63;
rWrite(0x02,(car.ksl<<6)|(mod.tl&63)); rWrite(0x02,(mod.ksl<<6)|(mod.tl&63));
} else { } else {
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
car.tl=c.value2&15; car.tl=c.value2&15;
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4)); if (c.chan<9) {
rWrite(0x30+c.chan,((15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)&15)|(chan[c.chan].state.opllPreset<<4));
}
} }
break; break;
} }
@ -632,14 +649,16 @@ void DivPlatformOPLL::forceIns() {
DivInstrumentFM::Operator& car=chan[i].state.op[1]; DivInstrumentFM::Operator& car=chan[i].state.op[1];
rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult)); rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult)); rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
rWrite(0x02,(car.ksl<<6)|(mod.tl&63)); rWrite(0x02,(mod.ksl<<6)|(mod.tl&63));
rWrite(0x03,(mod.ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); rWrite(0x03,(car.ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
rWrite(0x04,(mod.ar<<4)|(mod.dr)); rWrite(0x04,(mod.ar<<4)|(mod.dr));
rWrite(0x05,(car.ar<<4)|(car.dr)); rWrite(0x05,(car.ar<<4)|(car.dr));
rWrite(0x06,(mod.sl<<4)|(mod.rr)); rWrite(0x06,(mod.sl<<4)|(mod.rr));
rWrite(0x07,(car.sl<<4)|(car.rr)); rWrite(0x07,(car.sl<<4)|(car.rr));
} }
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4)); if (i<9) {
rWrite(0x30+i,((15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)&15)|(chan[i].state.opllPreset<<4));
}
if (!(i>=6 && properDrums)) { if (!(i>=6 && properDrums)) {
if (chan[i].active) { if (chan[i].active) {
chan[i].keyOn=true; chan[i].keyOn=true;

View file

@ -157,12 +157,6 @@ void PCE_PSG::RecalcUOFunc(int chnum)
//printf("UO Update: %d, %02x\n", chnum, ch->control); //printf("UO Update: %d, %02x\n", chnum, ch->control);
// what is this?
if (lfoctrl&3 && chnum==1) {
ch->UpdateOutput = &PCE_PSG::UpdateOutput_Off;
return;
}
if((revision != REVISION_HUC6280 && !(ch->control & 0xC0)) || (revision == REVISION_HUC6280 && !(ch->control & 0x80))) if((revision != REVISION_HUC6280 && !(ch->control & 0xC0)) || (revision == REVISION_HUC6280 && !(ch->control & 0x80)))
ch->UpdateOutput = &PCE_PSG::UpdateOutput_Off; ch->UpdateOutput = &PCE_PSG::UpdateOutput_Off;
else if(ch->noisectrl & ch->control & 0x80) else if(ch->noisectrl & ch->control & 0x80)

View file

@ -1540,6 +1540,7 @@ const char* aboutLine[]={
"NikonTeen", "NikonTeen",
"SuperJet Spade", "SuperJet Spade",
"TheDuccinator", "TheDuccinator",
"TheRealHedgehogSonic",
"tildearrow", "tildearrow",
"Ultraprogramer", "Ultraprogramer",
"", "",
@ -5439,7 +5440,11 @@ void FurnaceGUI::parseKeybinds() {
void FurnaceGUI::applyUISettings() { void FurnaceGUI::applyUISettings() {
ImGuiStyle sty; ImGuiStyle sty;
ImGui::StyleColorsDark(&sty); if (settings.guiColorsBase) {
ImGui::StyleColorsLight(&sty);
} else {
ImGui::StyleColorsDark(&sty);
}
if (settings.dpiScale>=0.5f) dpiScale=settings.dpiScale; if (settings.dpiScale>=0.5f) dpiScale=settings.dpiScale;
@ -5540,8 +5545,14 @@ void FurnaceGUI::applyUISettings() {
primaryHover.w=primaryActive.w; primaryHover.w=primaryActive.w;
primary.w=primaryActive.w; primary.w=primaryActive.w;
ImGui::ColorConvertRGBtoHSV(primaryActive.x,primaryActive.y,primaryActive.z,hue,sat,val); ImGui::ColorConvertRGBtoHSV(primaryActive.x,primaryActive.y,primaryActive.z,hue,sat,val);
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.5,primaryHover.x,primaryHover.y,primaryHover.z); if (settings.guiColorsBase) {
ImGui::ColorConvertHSVtoRGB(hue,sat*0.8,val*0.35,primary.x,primary.y,primary.z); primary=primaryActive;
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.9,primaryHover.x,primaryHover.y,primaryHover.z);
ImGui::ColorConvertHSVtoRGB(hue,sat,val*0.5,primaryActive.x,primaryActive.y,primaryActive.z);
} else {
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.5,primaryHover.x,primaryHover.y,primaryHover.z);
ImGui::ColorConvertHSVtoRGB(hue,sat*0.8,val*0.35,primary.x,primary.y,primary.z);
}
ImVec4 secondaryActive=uiColors[GUI_COLOR_ACCENT_SECONDARY]; ImVec4 secondaryActive=uiColors[GUI_COLOR_ACCENT_SECONDARY];
ImVec4 secondaryHover, secondary, secondarySemiActive; ImVec4 secondaryHover, secondary, secondarySemiActive;
@ -5549,9 +5560,16 @@ void FurnaceGUI::applyUISettings() {
secondaryHover.w=secondaryActive.w; secondaryHover.w=secondaryActive.w;
secondary.w=secondaryActive.w; secondary.w=secondaryActive.w;
ImGui::ColorConvertRGBtoHSV(secondaryActive.x,secondaryActive.y,secondaryActive.z,hue,sat,val); ImGui::ColorConvertRGBtoHSV(secondaryActive.x,secondaryActive.y,secondaryActive.z,hue,sat,val);
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.75,secondarySemiActive.x,secondarySemiActive.y,secondarySemiActive.z); if (settings.guiColorsBase) {
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.5,secondaryHover.x,secondaryHover.y,secondaryHover.z); secondary=secondaryActive;
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.25,secondary.x,secondary.y,secondary.z); ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.7,secondarySemiActive.x,secondarySemiActive.y,secondarySemiActive.z);
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.9,secondaryHover.x,secondaryHover.y,secondaryHover.z);
ImGui::ColorConvertHSVtoRGB(hue,sat,val*0.5,secondaryActive.x,secondaryActive.y,secondaryActive.z);
} else {
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.75,secondarySemiActive.x,secondarySemiActive.y,secondarySemiActive.z);
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.5,secondaryHover.x,secondaryHover.y,secondaryHover.z);
ImGui::ColorConvertHSVtoRGB(hue,sat*0.9,val*0.25,secondary.x,secondary.y,secondary.z);
}
sty.Colors[ImGuiCol_WindowBg]=uiColors[GUI_COLOR_FRAME_BACKGROUND]; sty.Colors[ImGuiCol_WindowBg]=uiColors[GUI_COLOR_FRAME_BACKGROUND];

View file

@ -493,6 +493,7 @@ class FurnaceGUI {
int statusDisplay; int statusDisplay;
float dpiScale; float dpiScale;
int viewPrevPattern; int viewPrevPattern;
int guiColorsBase;
unsigned int maxUndoSteps; unsigned int maxUndoSteps;
String mainFontPath; String mainFontPath;
String patFontPath; String patFontPath;
@ -533,6 +534,7 @@ class FurnaceGUI {
statusDisplay(0), statusDisplay(0),
dpiScale(0.0f), dpiScale(0.0f),
viewPrevPattern(1), viewPrevPattern(1),
guiColorsBase(0),
maxUndoSteps(100), maxUndoSteps(100),
mainFontPath(""), mainFontPath(""),
patFontPath(""), patFontPath(""),

View file

@ -863,6 +863,7 @@ void FurnaceGUI::drawInsEdit() {
bool willDisplayOps=true; bool willDisplayOps=true;
if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false; if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false;
if (!willDisplayOps && ins->type==DIV_INS_OPLL) { if (!willDisplayOps && ins->type==DIV_INS_OPLL) {
ins->fm.op[1].tl&=15;
P(ImGui::SliderScalar("Volume##TL",ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable P(ImGui::SliderScalar("Volume##TL",ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable
} }
if (willDisplayOps) if (ImGui::BeginTable("FMOperators",2,ImGuiTableFlags_SizingStretchSame)) { if (willDisplayOps) if (ImGui::BeginTable("FMOperators",2,ImGuiTableFlags_SizingStretchSame)) {
@ -917,6 +918,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
op.ar&=maxArDr;
P(ImGui::SliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable P(ImGui::SliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_AR)); ImGui::Text("%s",FM_NAME(FM_AR));
@ -924,6 +926,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
op.dr&=maxArDr;
P(ImGui::SliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable P(ImGui::SliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_DR)); ImGui::Text("%s",FM_NAME(FM_DR));
@ -954,6 +957,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
op.tl&=maxTl;
P(ImGui::SliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable P(ImGui::SliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_TL)); ImGui::Text("%s",FM_NAME(FM_TL));
@ -1280,6 +1284,9 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_PCE || ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_PCE || ins->type==DIV_INS_AMIGA) {
dutyMax=0; dutyMax=0;
} }
if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) {
dutyMax=0;
}
bool dutyIsRel=(ins->type==DIV_INS_C64 && !ins->c64.dutyIsAbs); bool dutyIsRel=(ins->type==DIV_INS_C64 && !ins->c64.dutyIsAbs);
int waveMax=(ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?3:63; int waveMax=(ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?3:63;
@ -1291,7 +1298,7 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_TIA) waveMax=15; if (ins->type==DIV_INS_TIA) waveMax=15;
if (ins->type==DIV_INS_C64) waveMax=4; if (ins->type==DIV_INS_C64) waveMax=4;
if (ins->type==DIV_INS_SAA1099) waveMax=2; if (ins->type==DIV_INS_SAA1099) waveMax=2;
if (ins->type==DIV_INS_FM) waveMax=0; if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPZ) waveMax=0;
if (ins->type==DIV_INS_MIKEY) waveMax=0; if (ins->type==DIV_INS_MIKEY) waveMax=0;
const char** waveNames=ayShapeBits; const char** waveNames=ayShapeBits;
@ -1311,9 +1318,9 @@ void FurnaceGUI::drawInsEdit() {
if (volMax>0) { if (volMax>0) {
NORMAL_MACRO(ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop,ins->std.volMacroRel,volMin,volMax,"vol",volumeLabel,160,ins->std.volMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_VOLUME],mmlString[0],volMin,volMax,NULL,false); NORMAL_MACRO(ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop,ins->std.volMacroRel,volMin,volMax,"vol",volumeLabel,160,ins->std.volMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_VOLUME],mmlString[0],volMin,volMax,NULL,false);
} }
NORMAL_MACRO(ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,ins->std.arpMacroRel,arpMacroScroll,arpMacroScroll+24,"arp","Arpeggio",160,ins->std.arpMacroOpen,false,NULL,true,&arpMacroScroll,(arpMode?0:-80),0,0,&ins->std.arpMacroMode,uiColors[GUI_COLOR_MACRO_PITCH],mmlString[1],-92,94,(ins->std.arpMacroMode?(&macroHoverNote):NULL),true); NORMAL_MACRO(ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,ins->std.arpMacroRel,arpMacroScroll,arpMacroScroll+24,"arp","Arpeggio",160,ins->std.arpMacroOpen,false,NULL,true,&arpMacroScroll,(arpMode?-60:-80),0,0,&ins->std.arpMacroMode,uiColors[GUI_COLOR_MACRO_PITCH],mmlString[1],-92,94,(ins->std.arpMacroMode?(&macroHoverNote):NULL),true);
if (dutyMax>0) { if (dutyMax>0) {
if (ins->type == DIV_INS_MIKEY) { if (ins->type==DIV_INS_MIKEY) {
NORMAL_MACRO(ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop,ins->std.dutyMacroRel,0,dutyMax,"duty",dutyLabel,160,ins->std.dutyMacroOpen,true,mikeyFeedbackBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,dutyMax,NULL,false); NORMAL_MACRO(ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop,ins->std.dutyMacroRel,0,dutyMax,"duty",dutyLabel,160,ins->std.dutyMacroOpen,true,mikeyFeedbackBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,dutyMax,NULL,false);
} }
else { else {

View file

@ -448,9 +448,15 @@ void FurnaceGUI::drawPattern() {
keyHit[i]=0.2; keyHit[i]=0.2;
e->keyHit[i]=false; e->keyHit[i]=false;
} }
chanHead.x*=0.25+keyHit[i]; chanHead.y*=0.25+keyHit[i]; chanHead.z*=0.25+keyHit[i]; if (settings.guiColorsBase) {
chanHeadActive.x*=0.8; chanHeadActive.y*=0.8; chanHeadActive.z*=0.8; chanHead.x*=1.0-keyHit[i]; chanHead.y*=1.0-keyHit[i]; chanHead.z*=1.0-keyHit[i];
chanHeadHover.x*=0.4+keyHit[i]; chanHeadHover.y*=0.4+keyHit[i]; chanHeadHover.z*=0.4+keyHit[i]; chanHeadActive.x*=0.5; chanHeadActive.y*=0.5; chanHeadActive.z*=0.5;
chanHeadHover.x*=0.9-keyHit[i]; chanHeadHover.y*=0.9-keyHit[i]; chanHeadHover.z*=0.9-keyHit[i];
} else {
chanHead.x*=0.25+keyHit[i]; chanHead.y*=0.25+keyHit[i]; chanHead.z*=0.25+keyHit[i];
chanHeadActive.x*=0.8; chanHeadActive.y*=0.8; chanHeadActive.z*=0.8;
chanHeadHover.x*=0.4+keyHit[i]; chanHeadHover.y*=0.4+keyHit[i]; chanHeadHover.z*=0.4+keyHit[i];
}
keyHit[i]-=0.02*60.0*ImGui::GetIO().DeltaTime; keyHit[i]-=0.02*60.0*ImGui::GetIO().DeltaTime;
if (keyHit[i]<0) keyHit[i]=0; if (keyHit[i]<0) keyHit[i]=0;
ImGui::PushStyleColor(ImGuiCol_Header,chanHead); ImGui::PushStyleColor(ImGuiCol_Header,chanHead);

View file

@ -425,6 +425,13 @@ void FurnaceGUI::drawSettings() {
if (ImGui::TreeNode("Color scheme")) { if (ImGui::TreeNode("Color scheme")) {
if (ImGui::TreeNode("General")) { if (ImGui::TreeNode("General")) {
ImGui::Text("Color scheme type:");
if (ImGui::RadioButton("Dark##gcb0",settings.guiColorsBase==0)) {
settings.guiColorsBase=0;
}
if (ImGui::RadioButton("Light##gcb1",settings.guiColorsBase==1)) {
settings.guiColorsBase=1;
}
UI_COLOR_CONFIG(GUI_COLOR_BACKGROUND,"Background"); UI_COLOR_CONFIG(GUI_COLOR_BACKGROUND,"Background");
UI_COLOR_CONFIG(GUI_COLOR_FRAME_BACKGROUND,"Window background"); UI_COLOR_CONFIG(GUI_COLOR_FRAME_BACKGROUND,"Window background");
UI_COLOR_CONFIG(GUI_COLOR_MODAL_BACKDROP,"Modal backdrop"); UI_COLOR_CONFIG(GUI_COLOR_MODAL_BACKDROP,"Modal backdrop");
@ -856,6 +863,7 @@ void FurnaceGUI::syncSettings() {
settings.statusDisplay=e->getConfInt("statusDisplay",0); settings.statusDisplay=e->getConfInt("statusDisplay",0);
settings.dpiScale=e->getConfFloat("dpiScale",0.0f); settings.dpiScale=e->getConfFloat("dpiScale",0.0f);
settings.viewPrevPattern=e->getConfInt("viewPrevPattern",1); settings.viewPrevPattern=e->getConfInt("viewPrevPattern",1);
settings.guiColorsBase=e->getConfInt("guiColorsBase",0);
// keybinds // keybinds
LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o); LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o);
@ -1051,6 +1059,7 @@ void FurnaceGUI::commitSettings() {
e->setConf("statusDisplay",settings.statusDisplay); e->setConf("statusDisplay",settings.statusDisplay);
e->setConf("dpiScale",settings.dpiScale); e->setConf("dpiScale",settings.dpiScale);
e->setConf("viewPrevPattern",settings.viewPrevPattern); e->setConf("viewPrevPattern",settings.viewPrevPattern);
e->setConf("guiColorsBase",settings.guiColorsBase);
PUT_UI_COLOR(GUI_COLOR_BACKGROUND); PUT_UI_COLOR(GUI_COLOR_BACKGROUND);
PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND); PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND);