diff --git a/demos/Coconut_Mall.fur b/demos/Coconut_Mall.fur new file mode 100644 index 000000000..471fcbec3 Binary files /dev/null and b/demos/Coconut_Mall.fur differ diff --git a/papers/format.md b/papers/format.md index ade5715de..dc052d038 100644 --- a/papers/format.md +++ b/papers/format.md @@ -119,13 +119,13 @@ size | description | - 0x06: NES - 5 channels | - 0x07: C64 (8580) - 3 channels | - 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: | - 0x42: Genesis extended - 13 channels | - 0x43: SMS (SN76489) + OPLL (YM2413) - 13 channels (compound!) | - 0x46: NES + VRC7 - 11 channels (compound!) | - 0x47: C64 (6581) - 3 channels - | - 0x49: Neo Geo extended - 16 channels + | - 0x49: Neo Geo CD extended - 16 channels | - bit 7 for non-DefleMask chips: | - 0x80: AY-3-8910 - 3 channels | - 0x81: Amiga - 4 channels @@ -164,10 +164,13 @@ size | description | - 0xa2: OPL drums (YM3526) - 11 channels | - 0xa3: OPL2 drums (YM3812) - 11 channels | - 0xa4: OPL3 drums (YMF262) - 20 channels - | - 0xa5: OPL3 4-op (YMF262) - 12 channels - | - 0xa6: OPL3 4-op + drums (YMF262) - 14 channels + | - 0xa5: Neo Geo (YM2610) - 14 channels + | - 0xa6: Neo Geo extended (YM2610) - 17 channels | - 0xa7: OPLL drums (YM2413) - 11 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 | - 0xe0: QSound - 19 channels | - (compound!) means that the system is composed of two or more chips, diff --git a/src/audio/rtmidi.h b/src/audio/rtmidi.h index 5fbba78fe..0803c3fcd 100644 --- a/src/audio/rtmidi.h +++ b/src/audio/rtmidi.h @@ -17,4 +17,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../../extern/rtmidi/RtMidi.h" \ No newline at end of file +#include "../../extern/rtmidi/RtMidi.h" +#include "taAudio.h" + +class TAMidiInRtMidi: public TAMidiIn { + +}; + +class TAMidiOutRtMidi: public TAMidiOut { + +}; \ No newline at end of file diff --git a/src/audio/taAudio.h b/src/audio/taAudio.h index 10712bc03..1f8c32305 100644 --- a/src/audio/taAudio.h +++ b/src/audio/taAudio.h @@ -20,6 +20,7 @@ #ifndef _TAAUDIO_H #define _TAAUDIO_H #include "../ta-utils.h" +#include #include struct SampleRateChangeEvent { @@ -116,14 +117,24 @@ struct TAMidiMessage { void submitSysEx(std::vector data); void done(); + + TAMidiMessage(): + type(0), + sysExData(NULL), + sysExLen(0) { + memset(&data,0,sizeof(data)); + } }; class TAMidiIn { + std::queue queue; public: + virtual bool gather(); bool next(TAMidiMessage& where); }; class TAMidiOut { + std::queue queue; public: bool send(TAMidiMessage& what); }; @@ -140,8 +151,8 @@ class TAAudio { void (*sampleRateChanged)(SampleRateChangeEvent); void (*bufferSizeChanged)(BufferSizeChangeEvent); public: - std::vector midiIn; - std::vector midiOut; + TAMidiIn* midiIn; + TAMidiOut* midiOut; void setSampleRateChangeCallback(void (*callback)(SampleRateChangeEvent)); void setBufferSizeChangeCallback(void (*callback)(BufferSizeChangeEvent)); diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 6f666306b..367bace65 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -133,17 +133,11 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s //OPN2_Write(&fm,0,0); } - psgClocks+=psg.rate; - while (psgClocks>=rate) { - psgOut=(psg.acquireOne()*3)>>3; - psgClocks-=rate; - } - - os[0]=(os[0]<<5)+psgOut; + os[0]=(os[0]<<5); if (os[0]<-32768) os[0]=-32768; 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]>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]; //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]>32767) os[0]=32767; - os[1]=os[1]+psgOut; if (os[1]<-32768) os[1]=-32768; if (os[1]>32767) os[1]=32767; @@ -391,13 +377,6 @@ void DivPlatformGenesis::tick() { 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) { @@ -442,10 +421,6 @@ int DivPlatformGenesis::toFreq(int freq) { } void DivPlatformGenesis::muteChannel(int ch, bool mute) { - if (ch>5) { - psg.muteChannel(ch-6,mute); - return; - } isMuted[ch]=mute; for (int j=0; j<4; j++) { unsigned short baseAddr=chanOffs[ch]|opOffs[j]; @@ -464,10 +439,6 @@ void DivPlatformGenesis::muteChannel(int ch, bool mute) { } int DivPlatformGenesis::dispatch(DivCommand c) { - if (c.chan>5) { - c.chan-=6; - return psg.dispatch(c); - } switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins); @@ -786,16 +757,13 @@ void DivPlatformGenesis::forceIns() { rWrite(0x2b,0x80); } immWrite(0x22,lfoValue); - psg.forceIns(); } void DivPlatformGenesis::toggleRegisterDump(bool enable) { DivDispatch::toggleRegisterDump(enable); - psg.toggleRegisterDump(enable); } void* DivPlatformGenesis::getChanState(int ch) { - if (ch>5) return psg.getChanState(ch-6); return &chan[ch]; } @@ -844,12 +812,6 @@ void DivPlatformGenesis::reset() { immWrite(0x22,lfoValue); delay=0; - - // PSG - psg.reset(); - psg.getRegisterWrites().clear(); - psgClocks=0; - psgOut=0; } bool DivPlatformGenesis::isStereo() { @@ -865,17 +827,14 @@ bool DivPlatformGenesis::keyOffAffectsPorta(int ch) { } void DivPlatformGenesis::notifyInsChange(int ins) { - for (int i=0; i<10; i++) { - if (i>5) { - psg.notifyInsChange(ins); - } else if (chan[i].ins==ins) { + for (int i=0; i<6; i++) { + if (chan[i].ins==ins) { chan[i].insChanged=true; } } } void DivPlatformGenesis::notifyInsDeletion(void* ins) { - psg.notifyInsDeletion(ins); } void DivPlatformGenesis::poke(unsigned int addr, unsigned short val) { @@ -904,7 +863,6 @@ void DivPlatformGenesis::setFlags(unsigned int flags) { } else { chipClock=COLOR_NTSC*15.0/7.0; } - psg.setFlags(flags==1); ladder=flags&0x80000000; OPN2_SetChipType(ladder?ym3438_mode_ym2612:0); if (useYMFM) { @@ -929,7 +887,6 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i isMuted[i]=false; } fm_ymfm=NULL; - psg.init(p,4,sugRate,flags==1); setFlags(flags); reset(); @@ -938,7 +895,6 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i void DivPlatformGenesis::quit() { if (fm_ymfm!=NULL) delete fm_ymfm; - psg.quit(); } DivPlatformGenesis::~DivPlatformGenesis() { diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 717c6c3dc..cd7b0396c 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -70,9 +70,6 @@ class DivPlatformGenesis: public DivDispatch { }; std::queue writes; ym3438_t fm; - DivPlatformSMS psg; - int psgClocks; - int psgOut; int delay; unsigned char lastBusy; diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index f49f48731..c6a8bf4de 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -133,7 +133,9 @@ void DivPlatformOPLL::tick() { if (chan[i].std.hadVol) { 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) { @@ -159,15 +161,15 @@ void DivPlatformOPLL::tick() { } if (chan[i].std.hadFb) { 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) { 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) { 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++) { @@ -201,9 +203,11 @@ void DivPlatformOPLL::tick() { if (m.hadTl) { op.tl=((j==1)?15:63)-m.tl; 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 { - 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) { op.ksl=m.ksl; 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 { - 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) { @@ -238,7 +242,9 @@ void DivPlatformOPLL::tick() { drumState&=~(0x10>>(chan[i].note%12)); immWrite(0x0e,0x20|drumState); } 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].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)); if (chan[i].freq>262143) chan[i].freq=262143; int freqt=toFreq(chan[i].freq); - chan[i].freqH=freqt>>8; chan[i].freqL=freqt&0xff; if (i>=6 && properDrums) { immWrite(0x10+drumSlot[i],freqt&0xff); immWrite(0x20+drumSlot[i],freqt>>8); } 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 (!isMuted[i]) { drumState|=(0x10>>(i-6)); immWrite(0x0e,0x20|drumState); } - chan[i].keyOn=false; + chan[i].keyOn=false; } else if (chan[i].keyOn && i>=6 && drums) { //printf("%d\n",chan[i].note%12); drumState|=(0x10>>(chan[i].note%12)); @@ -279,7 +287,11 @@ void DivPlatformOPLL::tick() { chan[i].keyOn=false; } else if ((chan[i].keyOn || chan[i].freqChanged) && i<9) { //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].freqChanged=false; @@ -381,8 +393,8 @@ int DivPlatformOPLL::dispatch(DivCommand c) { 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(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(0x03,(mod.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb); + rWrite(0x02,(mod.ksl<<6)|(mod.tl&63)); + 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(0x05,(car.ar<<4)|(car.dr)); rWrite(0x06,(mod.sl<<4)|(mod.rr)); @@ -410,7 +422,9 @@ int DivPlatformOPLL::dispatch(DivCommand c) { 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(0x38,drumVol[3]|(drumVol[2]<<4)); break; - } - if (c.chan<6 || !drums) { - 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)); + } else 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)); + } } break; } @@ -541,10 +556,10 @@ int DivPlatformOPLL::dispatch(DivCommand c) { } case DIV_CMD_FM_FB: { if (c.chan>=9 && !properDrums) return 0; - DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; - //DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; + //DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; + DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; 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; } @@ -565,13 +580,15 @@ int DivPlatformOPLL::dispatch(DivCommand c) { if (c.chan>=9 && !properDrums) return 0; if (c.value==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; - rWrite(0x02,(car.ksl<<6)|(mod.tl&63)); + rWrite(0x02,(mod.ksl<<6)|(mod.tl&63)); } else { DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; 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; } @@ -632,14 +649,16 @@ void DivPlatformOPLL::forceIns() { 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(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(0x03,(mod.ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); + rWrite(0x02,(mod.ksl<<6)|(mod.tl&63)); + 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(0x05,(car.ar<<4)|(car.dr)); rWrite(0x06,(mod.sl<<4)|(mod.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 (chan[i].active) { chan[i].keyOn=true; diff --git a/src/engine/platform/sound/pce_psg.cpp b/src/engine/platform/sound/pce_psg.cpp index ed71e0fd2..f9c1ee099 100644 --- a/src/engine/platform/sound/pce_psg.cpp +++ b/src/engine/platform/sound/pce_psg.cpp @@ -157,12 +157,6 @@ void PCE_PSG::RecalcUOFunc(int chnum) //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))) ch->UpdateOutput = &PCE_PSG::UpdateOutput_Off; else if(ch->noisectrl & ch->control & 0x80) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 0aeeb129e..ef0e0d86f 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1540,6 +1540,7 @@ const char* aboutLine[]={ "NikonTeen", "SuperJet Spade", "TheDuccinator", + "TheRealHedgehogSonic", "tildearrow", "Ultraprogramer", "", @@ -5439,7 +5440,11 @@ void FurnaceGUI::parseKeybinds() { void FurnaceGUI::applyUISettings() { ImGuiStyle sty; - ImGui::StyleColorsDark(&sty); + if (settings.guiColorsBase) { + ImGui::StyleColorsLight(&sty); + } else { + ImGui::StyleColorsDark(&sty); + } if (settings.dpiScale>=0.5f) dpiScale=settings.dpiScale; @@ -5540,8 +5545,14 @@ void FurnaceGUI::applyUISettings() { primaryHover.w=primaryActive.w; primary.w=primaryActive.w; 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); - ImGui::ColorConvertHSVtoRGB(hue,sat*0.8,val*0.35,primary.x,primary.y,primary.z); + if (settings.guiColorsBase) { + 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 secondaryHover, secondary, secondarySemiActive; @@ -5549,9 +5560,16 @@ void FurnaceGUI::applyUISettings() { secondaryHover.w=secondaryActive.w; secondary.w=secondaryActive.w; 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); - 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); + if (settings.guiColorsBase) { + secondary=secondaryActive; + 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]; diff --git a/src/gui/gui.h b/src/gui/gui.h index e41d71450..dee44f59c 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -493,6 +493,7 @@ class FurnaceGUI { int statusDisplay; float dpiScale; int viewPrevPattern; + int guiColorsBase; unsigned int maxUndoSteps; String mainFontPath; String patFontPath; @@ -533,6 +534,7 @@ class FurnaceGUI { statusDisplay(0), dpiScale(0.0f), viewPrevPattern(1), + guiColorsBase(0), maxUndoSteps(100), mainFontPath(""), patFontPath(""), diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 408c3c150..3f5ac067d 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -863,6 +863,7 @@ void FurnaceGUI::drawInsEdit() { bool willDisplayOps=true; if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false; 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 } if (willDisplayOps) if (ImGui::BeginTable("FMOperators",2,ImGuiTableFlags_SizingStretchSame)) { @@ -917,6 +918,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + op.ar&=maxArDr; P(ImGui::SliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_AR)); @@ -924,6 +926,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + op.dr&=maxArDr; P(ImGui::SliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_DR)); @@ -954,6 +957,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + op.tl&=maxTl; P(ImGui::SliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable ImGui::TableNextColumn(); 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) { 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); 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_C64) waveMax=4; 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; const char** waveNames=ayShapeBits; @@ -1311,9 +1318,9 @@ void FurnaceGUI::drawInsEdit() { 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.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?(¯oHoverNote):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?(¯oHoverNote):NULL),true); 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); } else { diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 7d9eb43ce..3d2f15cb8 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -448,9 +448,15 @@ void FurnaceGUI::drawPattern() { keyHit[i]=0.2; e->keyHit[i]=false; } - 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]; + if (settings.guiColorsBase) { + chanHead.x*=1.0-keyHit[i]; chanHead.y*=1.0-keyHit[i]; chanHead.z*=1.0-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; if (keyHit[i]<0) keyHit[i]=0; ImGui::PushStyleColor(ImGuiCol_Header,chanHead); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 136e95122..e40d47a13 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -425,6 +425,13 @@ void FurnaceGUI::drawSettings() { if (ImGui::TreeNode("Color scheme")) { 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_FRAME_BACKGROUND,"Window background"); UI_COLOR_CONFIG(GUI_COLOR_MODAL_BACKDROP,"Modal backdrop"); @@ -856,6 +863,7 @@ void FurnaceGUI::syncSettings() { settings.statusDisplay=e->getConfInt("statusDisplay",0); settings.dpiScale=e->getConfFloat("dpiScale",0.0f); settings.viewPrevPattern=e->getConfInt("viewPrevPattern",1); + settings.guiColorsBase=e->getConfInt("guiColorsBase",0); // keybinds LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o); @@ -1051,6 +1059,7 @@ void FurnaceGUI::commitSettings() { e->setConf("statusDisplay",settings.statusDisplay); e->setConf("dpiScale",settings.dpiScale); e->setConf("viewPrevPattern",settings.viewPrevPattern); + e->setConf("guiColorsBase",settings.guiColorsBase); PUT_UI_COLOR(GUI_COLOR_BACKGROUND); PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND);