Merge branch 'master' of https://github.com/tildearrow/furnace into bubsys
This commit is contained in:
commit
a7c750a44e
|
@ -105,7 +105,7 @@ struct DivInstrumentFM {
|
||||||
fb(0),
|
fb(0),
|
||||||
fms(0),
|
fms(0),
|
||||||
ams(0),
|
ams(0),
|
||||||
ops(4),
|
ops(2),
|
||||||
opllPreset(0),
|
opllPreset(0),
|
||||||
fixedDrums(false),
|
fixedDrums(false),
|
||||||
kickFreq(0x520),
|
kickFreq(0x520),
|
||||||
|
@ -115,11 +115,12 @@ struct DivInstrumentFM {
|
||||||
fb=4;
|
fb=4;
|
||||||
op[0].tl=42;
|
op[0].tl=42;
|
||||||
op[0].ar=31;
|
op[0].ar=31;
|
||||||
op[0].dr=8;
|
op[0].dr=2;
|
||||||
op[0].sl=15;
|
op[0].sl=15;
|
||||||
op[0].rr=3;
|
op[0].rr=3;
|
||||||
op[0].mult=5;
|
op[0].mult=5;
|
||||||
op[0].dt=5;
|
op[0].dt=5;
|
||||||
|
op[0].rs=3;
|
||||||
|
|
||||||
op[2].tl=18;
|
op[2].tl=18;
|
||||||
op[2].ar=31;
|
op[2].ar=31;
|
||||||
|
@ -129,13 +130,14 @@ struct DivInstrumentFM {
|
||||||
op[2].mult=1;
|
op[2].mult=1;
|
||||||
op[2].dt=0;
|
op[2].dt=0;
|
||||||
|
|
||||||
op[1].tl=48;
|
op[1].tl=64;
|
||||||
op[1].ar=31;
|
op[1].ar=31;
|
||||||
op[1].dr=4;
|
op[1].dr=2;
|
||||||
op[1].sl=11;
|
op[1].sl=11;
|
||||||
op[1].rr=1;
|
op[1].rr=8;
|
||||||
op[1].mult=1;
|
op[1].mult=1;
|
||||||
op[1].dt=5;
|
op[1].dt=5;
|
||||||
|
op[1].rs=2;
|
||||||
|
|
||||||
op[3].tl=2;
|
op[3].tl=2;
|
||||||
op[3].ar=31;
|
op[3].ar=31;
|
||||||
|
|
|
@ -48,6 +48,10 @@ const unsigned short chanMapOPL2[20]={
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, N, N, N, N, N, N, N, N, N, N, N
|
0, 1, 2, 3, 4, 5, 6, 7, 8, N, N, N, N, N, N, N, N, N, N, N
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned short chanMapOPL2Drums[20]={
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 7, N, N, N, N, N, N, N, N, N
|
||||||
|
};
|
||||||
|
|
||||||
const unsigned char* slotsOPL2[4]={
|
const unsigned char* slotsOPL2[4]={
|
||||||
slotsOPL2i[0],
|
slotsOPL2i[0],
|
||||||
slotsOPL2i[1],
|
slotsOPL2i[1],
|
||||||
|
@ -71,7 +75,7 @@ const unsigned char slotsOPL3i[4][20]={
|
||||||
|
|
||||||
const unsigned char slotsOPL3Drumsi[4][20]={
|
const unsigned char slotsOPL3Drumsi[4][20]={
|
||||||
{0, 6, 1, 7, 2, 8, 18, 24, 19, 25, 20, 26, 30, 31, 32, 12, 16, 14, 17, 13}, // OP1
|
{0, 6, 1, 7, 2, 8, 18, 24, 19, 25, 20, 26, 30, 31, 32, 12, 16, 14, 17, 13}, // OP1
|
||||||
{3, 9, 4, 10, 5, 11, 21, 27, 22, 28, 23, 29, 33, 34, 35, N, N, N, N, N}, // OP2
|
{3, 9, 4, 10, 5, 11, 21, 27, 22, 28, 23, 29, 33, 34, 35, 15, N, N, N, N}, // OP2
|
||||||
{6, N, 7, N, 8, N, 24, N, 25, N, 26, N, N, N, N, N, N, N, N, N}, // OP3
|
{6, N, 7, N, 8, N, 24, N, 25, N, 26, N, N, N, N, N, N, N, N, N}, // OP3
|
||||||
{9, N, 10, N, 11, N, 27, N, 28, N, 29, N, N, N, N, N, N, N, N, N} // OP4
|
{9, N, 10, N, 11, N, 27, N, 28, N, 29, N, N, N, N, N, N, N, N, N} // OP4
|
||||||
};
|
};
|
||||||
|
@ -80,6 +84,10 @@ const unsigned short chanMapOPL3[20]={
|
||||||
0, 3, 1, 4, 2, 5, 0x100, 0x103, 0x101, 0x104, 0x102, 0x105, 0x106, 0x107, 0x108, 6, 7, 8, N, N
|
0, 3, 1, 4, 2, 5, 0x100, 0x103, 0x101, 0x104, 0x102, 0x105, 0x106, 0x107, 0x108, 6, 7, 8, N, N
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned short chanMapOPL3Drums[20]={
|
||||||
|
0, 3, 1, 4, 2, 5, 0x100, 0x103, 0x101, 0x104, 0x102, 0x105, 0x106, 0x107, 0x108, 6, 7, 8, 8, 7
|
||||||
|
};
|
||||||
|
|
||||||
const unsigned char* slotsOPL3[4]={
|
const unsigned char* slotsOPL3[4]={
|
||||||
slotsOPL3i[0],
|
slotsOPL3i[0],
|
||||||
slotsOPL3i[1],
|
slotsOPL3i[1],
|
||||||
|
@ -224,7 +232,7 @@ void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformOPL::tick() {
|
void DivPlatformOPL::tick() {
|
||||||
for (int i=0; i<melodicChans; i++) {
|
for (int i=0; i<totalChans; i++) {
|
||||||
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
|
||||||
|
@ -266,7 +274,6 @@ void DivPlatformOPL::tick() {
|
||||||
|
|
||||||
if (chan[i].std.hadAlg) {
|
if (chan[i].std.hadAlg) {
|
||||||
chan[i].state.alg=chan[i].std.alg;
|
chan[i].state.alg=chan[i].std.alg;
|
||||||
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
@ -356,9 +363,11 @@ void DivPlatformOPL::tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].keyOn || chan[i].keyOff) {
|
if (i<melodicChans) {
|
||||||
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
if (chan[i].keyOn || chan[i].keyOff) {
|
||||||
chan[i].keyOff=false;
|
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
||||||
|
chan[i].keyOff=false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +380,22 @@ void DivPlatformOPL::tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update drums
|
||||||
|
if (properDrums) {
|
||||||
|
bool updateDrums=false;
|
||||||
|
for (int i=melodicChans; i<totalChans; i++) {
|
||||||
|
if (chan[i].keyOn || chan[i].keyOff) {
|
||||||
|
drumState&=~(1<<(totalChans-i-1));
|
||||||
|
updateDrums=true;
|
||||||
|
chan[i].keyOff=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDrums) {
|
||||||
|
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<512; i++) {
|
for (int i=0; i<512; i++) {
|
||||||
if (pendingWrites[i]!=oldWrites[i]) {
|
if (pendingWrites[i]!=oldWrites[i]) {
|
||||||
immWrite(i,pendingWrites[i]&0xff);
|
immWrite(i,pendingWrites[i]&0xff);
|
||||||
|
@ -378,7 +403,8 @@ void DivPlatformOPL::tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<melodicChans; i++) {
|
bool updateDrums=false;
|
||||||
|
for (int i=0; i<totalChans; i++) {
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
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>131071) chan[i].freq=131071;
|
if (chan[i].freq>131071) chan[i].freq=131071;
|
||||||
|
@ -387,14 +413,29 @@ void DivPlatformOPL::tick() {
|
||||||
chan[i].freqL=freqt&0xff;
|
chan[i].freqL=freqt&0xff;
|
||||||
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
|
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
|
||||||
}
|
}
|
||||||
if (chan[i].keyOn) {
|
if (i<melodicChans) {
|
||||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
|
if (chan[i].keyOn) {
|
||||||
chan[i].keyOn=false;
|
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
|
||||||
} else if (chan[i].freqChanged) {
|
chan[i].keyOn=false;
|
||||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
|
} else if (chan[i].freqChanged) {
|
||||||
|
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (chan[i].keyOn) {
|
||||||
|
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH);
|
||||||
|
drumState|=(1<<(totalChans-i-1));
|
||||||
|
updateDrums=true;
|
||||||
|
chan[i].keyOn=false;
|
||||||
|
} else if (chan[i].freqChanged) {
|
||||||
|
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (updateDrums) {
|
||||||
|
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPLL_C_NUM 686
|
#define OPLL_C_NUM 686
|
||||||
|
@ -476,8 +517,7 @@ void DivPlatformOPL::muteChannel(int ch, bool mute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformOPL::dispatch(DivCommand c) {
|
int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
// TODO: drums mode!
|
if (c.chan>=totalChans) return 0;
|
||||||
if (c.chan>=melodicChans) return 0;
|
|
||||||
// ineffective in 4-op mode
|
// ineffective in 4-op mode
|
||||||
if (oplType==3 && c.chan<14 && (c.chan&1) && c.cmd!=DIV_CMD_GET_VOLMAX && c.cmd!=DIV_ALWAYS_SET_VOLUME) {
|
if (oplType==3 && c.chan<14 && (c.chan&1) && c.cmd!=DIV_CMD_GET_VOLMAX && c.cmd!=DIV_ALWAYS_SET_VOLUME) {
|
||||||
if (chan[c.chan-1].fourOp) return 0;
|
if (chan[c.chan-1].fourOp) return 0;
|
||||||
|
@ -542,7 +582,19 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
chan[c.chan].insChanged=false;
|
chan[c.chan].insChanged=false;
|
||||||
|
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
if (c.chan>=melodicChans && chan[c.chan].state.opllPreset==16 && chan[c.chan].state.fixedDrums) { // drums
|
||||||
|
if (c.chan==melodicChans) {
|
||||||
|
chan[c.chan].baseFreq=(chan[c.chan].state.kickFreq&1023)<<(chan[c.chan].state.kickFreq>>10);
|
||||||
|
} else if (c.chan==melodicChans+1 || c.chan==melodicChans+4) {
|
||||||
|
chan[c.chan].baseFreq=(chan[c.chan].state.snareHatFreq&1023)<<(chan[c.chan].state.snareHatFreq>>10);
|
||||||
|
} else if (c.chan==melodicChans+2 || c.chan==melodicChans+3) {
|
||||||
|
chan[c.chan].baseFreq=(chan[c.chan].state.tomTopFreq&1023)<<(chan[c.chan].state.tomTopFreq>>10);
|
||||||
|
} else {
|
||||||
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||||
|
}
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
@ -748,8 +800,19 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_EXTCH: {
|
case DIV_CMD_FM_EXTCH: {
|
||||||
|
if (!properDrumsSys) break;
|
||||||
properDrums=c.value;
|
properDrums=c.value;
|
||||||
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
|
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
|
||||||
|
slots=properDrums?slotsDrums:slotsNonDrums;
|
||||||
|
if (oplType==3) {
|
||||||
|
chanMap=properDrums?chanMapOPL3Drums:chanMapOPL3;
|
||||||
|
melodicChans=properDrums?15:18;
|
||||||
|
totalChans=properDrums?20:18;
|
||||||
|
} else {
|
||||||
|
chanMap=properDrums?chanMapOPL2Drums:chanMapOPL2;
|
||||||
|
melodicChans=properDrums?6:9;
|
||||||
|
totalChans=properDrums?11:9;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_ALWAYS_SET_VOLUME:
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
|
@ -772,7 +835,16 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformOPL::forceIns() {
|
void DivPlatformOPL::forceIns() {
|
||||||
for (int i=0; i<melodicChans; i++) {
|
if (oplType==3) {
|
||||||
|
chanMap=properDrums?chanMapOPL3Drums:chanMapOPL3;
|
||||||
|
melodicChans=properDrums?15:18;
|
||||||
|
totalChans=properDrums?20:18;
|
||||||
|
} else {
|
||||||
|
chanMap=properDrums?chanMapOPL2Drums:chanMapOPL2;
|
||||||
|
melodicChans=properDrums?6:9;
|
||||||
|
totalChans=properDrums?11:9;
|
||||||
|
}
|
||||||
|
for (int i=0; i<totalChans; i++) {
|
||||||
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
||||||
chan[i].insChanged=true;
|
chan[i].insChanged=true;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
|
@ -845,6 +917,18 @@ void DivPlatformOPL::reset() {
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
properDrums=properDrumsSys;
|
||||||
|
if (oplType==3) {
|
||||||
|
chanMap=properDrums?chanMapOPL3Drums:chanMapOPL3;
|
||||||
|
melodicChans=properDrums?15:18;
|
||||||
|
totalChans=properDrums?20:18;
|
||||||
|
} else {
|
||||||
|
chanMap=properDrums?chanMapOPL2Drums:chanMapOPL2;
|
||||||
|
melodicChans=properDrums?6:9;
|
||||||
|
totalChans=properDrums?11:9;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<totalChans; i++) {
|
for (int i=0; i<totalChans; i++) {
|
||||||
chan[i]=DivPlatformOPL::Channel();
|
chan[i]=DivPlatformOPL::Channel();
|
||||||
chan[i].vol=0x3f;
|
chan[i].vol=0x3f;
|
||||||
|
@ -858,7 +942,6 @@ void DivPlatformOPL::reset() {
|
||||||
|
|
||||||
lastBusy=60;
|
lastBusy=60;
|
||||||
lfoValue=8;
|
lfoValue=8;
|
||||||
properDrums=properDrumsSys;
|
|
||||||
drumState=0;
|
drumState=0;
|
||||||
|
|
||||||
drumVol[0]=0;
|
drumVol[0]=0;
|
||||||
|
@ -879,6 +962,8 @@ void DivPlatformOPL::reset() {
|
||||||
dam=false;
|
dam=false;
|
||||||
dvb=false;
|
dvb=false;
|
||||||
delay=0;
|
delay=0;
|
||||||
|
|
||||||
|
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivPlatformOPL::isStereo() {
|
bool DivPlatformOPL::isStereo() {
|
||||||
|
@ -927,7 +1012,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
|
||||||
slotsNonDrums=slotsOPL2;
|
slotsNonDrums=slotsOPL2;
|
||||||
slotsDrums=slotsOPL2Drums;
|
slotsDrums=slotsOPL2Drums;
|
||||||
slots=drums?slotsDrums:slotsNonDrums;
|
slots=drums?slotsDrums:slotsNonDrums;
|
||||||
chanMap=chanMapOPL2;
|
chanMap=drums?chanMapOPL2Drums:chanMapOPL2;
|
||||||
chipFreqBase=9440540*0.25;
|
chipFreqBase=9440540*0.25;
|
||||||
chans=9;
|
chans=9;
|
||||||
melodicChans=drums?6:9;
|
melodicChans=drums?6:9;
|
||||||
|
@ -937,7 +1022,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
|
||||||
slotsNonDrums=slotsOPL3;
|
slotsNonDrums=slotsOPL3;
|
||||||
slotsDrums=slotsOPL3Drums;
|
slotsDrums=slotsOPL3Drums;
|
||||||
slots=drums?slotsDrums:slotsNonDrums;
|
slots=drums?slotsDrums:slotsNonDrums;
|
||||||
chanMap=chanMapOPL3;
|
chanMap=drums?chanMapOPL3Drums:chanMapOPL3;
|
||||||
chipFreqBase=9440540;
|
chipFreqBase=9440540;
|
||||||
chans=18;
|
chans=18;
|
||||||
melodicChans=drums?15:18;
|
melodicChans=drums?15:18;
|
||||||
|
@ -997,7 +1082,7 @@ int DivPlatformOPL::init(DivEngine* p, int channels, int sugRate, unsigned int f
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
return 10;
|
return totalChans;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformOPL::quit() {
|
void DivPlatformOPL::quit() {
|
||||||
|
|
|
@ -6952,6 +6952,10 @@ bool FurnaceGUI::finish() {
|
||||||
|
|
||||||
FurnaceGUI::FurnaceGUI():
|
FurnaceGUI::FurnaceGUI():
|
||||||
e(NULL),
|
e(NULL),
|
||||||
|
sampleTex(NULL),
|
||||||
|
sampleTexW(0),
|
||||||
|
sampleTexH(0),
|
||||||
|
updateSampleTex(true),
|
||||||
quit(false),
|
quit(false),
|
||||||
warnQuit(false),
|
warnQuit(false),
|
||||||
willCommit(false),
|
willCommit(false),
|
||||||
|
|
|
@ -466,6 +466,10 @@ class FurnaceGUI {
|
||||||
SDL_Window* sdlWin;
|
SDL_Window* sdlWin;
|
||||||
SDL_Renderer* sdlRend;
|
SDL_Renderer* sdlRend;
|
||||||
|
|
||||||
|
SDL_Texture* sampleTex;
|
||||||
|
int sampleTexW, sampleTexH;
|
||||||
|
bool updateSampleTex;
|
||||||
|
|
||||||
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile;
|
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile;
|
||||||
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport, workingDirVGMExport, workingDirFont;
|
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport, workingDirVGMExport, workingDirFont;
|
||||||
String mmlString[13];
|
String mmlString[13];
|
||||||
|
|
|
@ -878,6 +878,39 @@ if (ImGui::BeginTable("MacroSpace",2)) { \
|
||||||
ImGui::EndTable(); \
|
ImGui::EndTable(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DRUM_FREQ(name,db,df,prop) \
|
||||||
|
ImGui::TableNextRow(); \
|
||||||
|
ImGui::TableNextColumn(); \
|
||||||
|
if (ins->type==DIV_INS_OPLL) { \
|
||||||
|
block=(prop>>9)&7; \
|
||||||
|
fNum=prop&511; \
|
||||||
|
} else { \
|
||||||
|
block=(prop>>10)&7; \
|
||||||
|
fNum=prop&1023; \
|
||||||
|
} \
|
||||||
|
ImGui::Text(name); \
|
||||||
|
ImGui::TableNextColumn(); \
|
||||||
|
if (ImGui::InputInt(db,&block,1,1)) { \
|
||||||
|
if (block<0) block=0; \
|
||||||
|
if (block>7) block=7; \
|
||||||
|
if (ins->type==DIV_INS_OPLL) { \
|
||||||
|
prop=(block<<9)|fNum; \
|
||||||
|
} else { \
|
||||||
|
prop=(block<<10)|fNum; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
ImGui::TableNextColumn(); \
|
||||||
|
if (ImGui::InputInt(df,&fNum,1,1)) { \
|
||||||
|
if (fNum<0) fNum=0; \
|
||||||
|
if (ins->type==DIV_INS_OPLL) { \
|
||||||
|
if (fNum>511) fNum=511; \
|
||||||
|
prop=(block<<9)|fNum; \
|
||||||
|
} else { \
|
||||||
|
if (fNum>1023) fNum=1023; \
|
||||||
|
prop=(block<<10)|fNum; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUI::drawInsEdit() {
|
void FurnaceGUI::drawInsEdit() {
|
||||||
if (nextWindow==GUI_WINDOW_INS_EDIT) {
|
if (nextWindow==GUI_WINDOW_INS_EDIT) {
|
||||||
insEditOpen=true;
|
insEditOpen=true;
|
||||||
|
@ -933,9 +966,11 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ins->fm.alg&=algMax;
|
ins->fm.alg&=algMax;
|
||||||
P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
|
P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
|
||||||
|
ImGui::BeginDisabled(ins->fm.opllPreset==16);
|
||||||
if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER
|
if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER
|
||||||
ins->fm.ops=fourOp?4:2;
|
ins->fm.ops=fourOp?4:2;
|
||||||
}
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
P(ImGui::SliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable
|
P(ImGui::SliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable
|
||||||
if (ImGui::Checkbox("Drums",&drums)) { PARAMETER
|
if (ImGui::Checkbox("Drums",&drums)) { PARAMETER
|
||||||
|
@ -984,7 +1019,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset==16) {
|
if ((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) {
|
||||||
|
ins->fm.ops=2;
|
||||||
P(ImGui::Checkbox("Fixed frequency mode",&ins->fm.fixedDrums));
|
P(ImGui::Checkbox("Fixed frequency mode",&ins->fm.fixedDrums));
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("when enabled, drums will be set to the specified frequencies, ignoring the note.");
|
ImGui::SetTooltip("when enabled, drums will be set to the specified frequencies, ignoring the note.");
|
||||||
|
@ -1001,59 +1037,9 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("FreqNum");
|
ImGui::Text("FreqNum");
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
DRUM_FREQ("Kick","##DBlock0","##DFreq0",ins->fm.kickFreq);
|
||||||
ImGui::TableNextColumn();
|
DRUM_FREQ("Snare/Hi-hat","##DBlock1","##DFreq1",ins->fm.snareHatFreq);
|
||||||
block=(ins->fm.kickFreq>>9)&7;
|
DRUM_FREQ("Tom/Top","##DBlock2","##DFreq2",ins->fm.tomTopFreq);
|
||||||
fNum=ins->fm.kickFreq&511;
|
|
||||||
ImGui::Text("Kick");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::InputInt("##DBlock0",&block,1,1)) {
|
|
||||||
if (block<0) block=0;
|
|
||||||
if (block>7) block=7;
|
|
||||||
ins->fm.kickFreq=(block<<9)|fNum;
|
|
||||||
}
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::InputInt("##DFreq0",&fNum,1,1)) {
|
|
||||||
if (fNum<0) fNum=0;
|
|
||||||
if (fNum>511) fNum=511;
|
|
||||||
ins->fm.kickFreq=(block<<9)|fNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
block=(ins->fm.snareHatFreq>>9)&7;
|
|
||||||
fNum=ins->fm.snareHatFreq&511;
|
|
||||||
ImGui::Text("Snare/Hi-hat");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::InputInt("##DBlock1",&block,1,1)) {
|
|
||||||
if (block<0) block=0;
|
|
||||||
if (block>7) block=7;
|
|
||||||
ins->fm.snareHatFreq=(block<<9)|fNum;
|
|
||||||
}
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::InputInt("##DFreq1",&fNum,1,1)) {
|
|
||||||
if (fNum<0) fNum=0;
|
|
||||||
if (fNum>511) fNum=511;
|
|
||||||
ins->fm.snareHatFreq=(block<<9)|fNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
block=(ins->fm.tomTopFreq>>9)&7;
|
|
||||||
fNum=ins->fm.tomTopFreq&511;
|
|
||||||
ImGui::Text("Tom/Top");
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::InputInt("##DBlock2",&block,1,1)) {
|
|
||||||
if (block<0) block=0;
|
|
||||||
if (block>7) block=7;
|
|
||||||
ins->fm.tomTopFreq=(block<<9)|fNum;
|
|
||||||
}
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
if (ImGui::InputInt("##DFreq2",&fNum,1,1)) {
|
|
||||||
if (fNum<0) fNum=0;
|
|
||||||
if (fNum>511) fNum=511;
|
|
||||||
ins->fm.tomTopFreq=(block<<9)|fNum;
|
|
||||||
}
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1073,7 +1059,15 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
|
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
|
||||||
ImGui::Dummy(ImVec2(dpiScale,dpiScale));
|
ImGui::Dummy(ImVec2(dpiScale,dpiScale));
|
||||||
ImGui::Text("OP%d",i+1);
|
if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) {
|
||||||
|
if (i==1) {
|
||||||
|
ImGui::Text("Envelope 2 (kick only)");
|
||||||
|
} else {
|
||||||
|
ImGui::Text("Envelope");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::Text("OP%d",i+1);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,13 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
#include "IconsFontAwesome4.h"
|
#include "IconsFontAwesome4.h"
|
||||||
#include "misc/cpp/imgui_stdlib.h"
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
#include "guiConst.h"
|
#include "guiConst.h"
|
||||||
|
#include <SDL_error.h>
|
||||||
|
#include <SDL_pixels.h>
|
||||||
|
#include <SDL_render.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
void FurnaceGUI::drawSampleEdit() {
|
void FurnaceGUI::drawSampleEdit() {
|
||||||
|
@ -40,45 +44,60 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
sampleType=sampleDepths[sample->depth];
|
sampleType=sampleDepths[sample->depth];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::InputText("Name",&sample->name);
|
ImGui::Text("Name");
|
||||||
if (ImGui::BeginCombo("Type",sampleType.c_str())) {
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
for (int i=0; i<17; i++) {
|
ImGui::InputText("##SampleName",&sample->name);
|
||||||
if (sampleDepths[i]==NULL) continue;
|
|
||||||
if (ImGui::Selectable(sampleDepths[i])) {
|
if (ImGui::BeginTable("SampleProps",4,ImGuiTableFlags_SizingStretchSame)) {
|
||||||
sample->depth=i;
|
ImGui::TableNextRow();
|
||||||
e->renderSamplesP();
|
ImGui::TableNextColumn();
|
||||||
}
|
if (ImGui::BeginCombo("Type",sampleType.c_str())) {
|
||||||
if (ImGui::IsItemHovered()) {
|
for (int i=0; i<17; i++) {
|
||||||
ImGui::SetTooltip("no undo for sample type change operations!");
|
if (sampleDepths[i]==NULL) continue;
|
||||||
|
if (ImGui::Selectable(sampleDepths[i])) {
|
||||||
|
sample->depth=i;
|
||||||
|
e->renderSamplesP();
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("no undo for sample type change operations!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
ImGui::EndCombo();
|
|
||||||
}
|
ImGui::TableNextColumn();
|
||||||
if (ImGui::InputInt("Rate (Hz)",&sample->rate,10,200)) {
|
if (ImGui::InputInt("Rate (Hz)",&sample->rate,10,200)) {
|
||||||
if (sample->rate<100) sample->rate=100;
|
if (sample->rate<100) sample->rate=100;
|
||||||
if (sample->rate>96000) sample->rate=96000;
|
if (sample->rate>96000) sample->rate=96000;
|
||||||
}
|
|
||||||
if (ImGui::InputInt("Pitch of C-4 (Hz)",&sample->centerRate,10,200)) {
|
|
||||||
if (sample->centerRate<100) sample->centerRate=100;
|
|
||||||
if (sample->centerRate>65535) sample->centerRate=65535;
|
|
||||||
}
|
|
||||||
ImGui::Text("effective rate: %dHz",e->getEffectiveSampleRate(sample->rate));
|
|
||||||
bool doLoop=(sample->loopStart>=0);
|
|
||||||
if (ImGui::Checkbox("Loop",&doLoop)) {
|
|
||||||
if (doLoop) {
|
|
||||||
sample->loopStart=0;
|
|
||||||
} else {
|
|
||||||
sample->loopStart=-1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (doLoop) {
|
ImGui::TableNextColumn();
|
||||||
ImGui::SameLine();
|
if (ImGui::InputInt("Pitch of C-4 (Hz)",&sample->centerRate,10,200)) {
|
||||||
if (ImGui::InputInt("##LoopPosition",&sample->loopStart,1,10)) {
|
if (sample->centerRate<100) sample->centerRate=100;
|
||||||
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
|
if (sample->centerRate>65535) sample->centerRate=65535;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
bool doLoop=(sample->loopStart>=0);
|
||||||
|
if (ImGui::Checkbox("Loop",&doLoop)) {
|
||||||
|
if (doLoop) {
|
||||||
sample->loopStart=0;
|
sample->loopStart=0;
|
||||||
|
} else {
|
||||||
|
sample->loopStart=-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (doLoop) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::InputInt("##LoopPosition",&sample->loopStart,1,10)) {
|
||||||
|
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
|
||||||
|
sample->loopStart=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (ImGui::Button("Apply")) {
|
if (ImGui::Button("Apply")) {
|
||||||
e->renderSamplesP();
|
e->renderSamplesP();
|
||||||
}
|
}
|
||||||
|
@ -89,8 +108,54 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(ICON_FA_VOLUME_OFF "##StopSample")) {
|
if (ImGui::Button(ICON_FA_VOLUME_OFF "##StopSample")) {
|
||||||
e->stopSamplePreview();
|
e->stopSamplePreview();
|
||||||
}
|
}*/
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImVec2 avail=ImGui::GetContentRegionAvail();
|
||||||
|
//int availX=avail.x;
|
||||||
|
int availY=avail.y;
|
||||||
|
|
||||||
|
if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y) {
|
||||||
|
if (sampleTex!=NULL) {
|
||||||
|
SDL_DestroyTexture(sampleTex);
|
||||||
|
sampleTex=NULL;
|
||||||
|
}
|
||||||
|
if (avail.x>=1 && avail.y>=1) {
|
||||||
|
logD("recreating sample texture.\n");
|
||||||
|
sampleTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ARGB8888,SDL_TEXTUREACCESS_STREAMING,avail.x,avail.y);
|
||||||
|
sampleTexW=avail.x;
|
||||||
|
sampleTexH=avail.y;
|
||||||
|
if (sampleTex==NULL) {
|
||||||
|
logE("error while creating sample texture! %s\n",SDL_GetError());
|
||||||
|
} else {
|
||||||
|
updateSampleTex=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampleTex!=NULL) {
|
||||||
|
if (updateSampleTex) {
|
||||||
|
unsigned char* data=NULL;
|
||||||
|
int pitch=0;
|
||||||
|
logD("updating sample texture.\n");
|
||||||
|
if (SDL_LockTexture(sampleTex,NULL,(void**)&data,&pitch)!=0) {
|
||||||
|
logE("error while locking sample texture! %s\n",SDL_GetError());
|
||||||
|
} else {
|
||||||
|
for (int i=0; i<pitch*availY; i+=4) {
|
||||||
|
data[i]=255;
|
||||||
|
data[i+1]=255;
|
||||||
|
data[i+2]=255;
|
||||||
|
data[i+3]=255;
|
||||||
|
}
|
||||||
|
SDL_UnlockTexture(sampleTex);
|
||||||
|
}
|
||||||
|
updateSampleTex=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Image(sampleTex,avail);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool considerations=false;
|
bool considerations=false;
|
||||||
ImGui::Text("notes:");
|
ImGui::Text("notes:");
|
||||||
if (sample->loopStart>=0) {
|
if (sample->loopStart>=0) {
|
||||||
|
@ -129,7 +194,7 @@ void FurnaceGUI::drawSampleEdit() {
|
||||||
}
|
}
|
||||||
if (!considerations) {
|
if (!considerations) {
|
||||||
ImGui::Text("- none");
|
ImGui::Text("- none");
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_SAMPLE_EDIT;
|
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_SAMPLE_EDIT;
|
||||||
|
|
Loading…
Reference in New Issue