Merge branch 'master' of https://github.com/tildearrow/furnace into ay_divider
* 'master' of https://github.com/tildearrow/furnace: (24 commits) GUI: remove insLoadAlwaysReplace setting GUI: right click menu for open instrument GUI: add a threshold for macro right click OPZ: remove debug printf GUI: add macro right click menu GUI: prepare for macro right click menu update gitignore add something prepare for something did i fix macOS build? GUI: macro edit improvements GUI: now add ability to load VMEM Update sysDef.cpp GUI: add an option for it add preliminary TX81Z SysEx response OPL: drum volume OPL: implement hard reset GUI: add icon size setting GUI: macro UI refactor, part 4 Fix WIN32 define timing in IGFD ...
This commit is contained in:
commit
a9a249fd4c
57 changed files with 6506 additions and 115 deletions
|
|
@ -2383,6 +2383,22 @@ void DivEngine::setMidiCallback(std::function<int(const TAMidiMessage&)> what) {
|
|||
midiCallback=what;
|
||||
}
|
||||
|
||||
bool DivEngine::sendMidiMessage(TAMidiMessage& msg) {
|
||||
if (output==NULL) {
|
||||
logW("output is NULL!");
|
||||
return false;
|
||||
}
|
||||
if (output->midiOut==NULL) {
|
||||
logW("MIDI output is NULL!");
|
||||
return false;
|
||||
}
|
||||
BUSY_BEGIN;
|
||||
logD("sending MIDI message...");
|
||||
bool ret=(output->midiOut->send(msg));
|
||||
BUSY_END;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DivEngine::synchronized(const std::function<void()>& what) {
|
||||
BUSY_BEGIN;
|
||||
what();
|
||||
|
|
@ -2632,6 +2648,8 @@ bool DivEngine::init() {
|
|||
// init config
|
||||
#ifdef _WIN32
|
||||
configPath=getWinConfigPath();
|
||||
#elif defined(ANDROID)
|
||||
configPath=SDL_GetPrefPath("tildearrow","furnace");
|
||||
#else
|
||||
struct stat st;
|
||||
char* home=getenv("HOME");
|
||||
|
|
|
|||
|
|
@ -826,6 +826,9 @@ class DivEngine {
|
|||
// if the specified function returns -2, note feedback will be inhibited.
|
||||
void setMidiCallback(std::function<int(const TAMidiMessage&)> what);
|
||||
|
||||
// send MIDI message
|
||||
bool sendMidiMessage(TAMidiMessage& msg);
|
||||
|
||||
// perform secure/sync operation
|
||||
void synchronized(const std::function<void()>& what);
|
||||
|
||||
|
|
|
|||
|
|
@ -166,13 +166,20 @@ struct DivInstrumentMacro {
|
|||
unsigned char len;
|
||||
signed char loop;
|
||||
signed char rel;
|
||||
|
||||
// the following variables are used by the GUI and not saved in the file
|
||||
int vScroll, vZoom;
|
||||
|
||||
|
||||
explicit DivInstrumentMacro(const String& n, bool initOpen=false):
|
||||
name(n),
|
||||
mode(0),
|
||||
open(initOpen),
|
||||
len(0),
|
||||
loop(-1),
|
||||
rel(-1) {
|
||||
rel(-1),
|
||||
vScroll(0),
|
||||
vZoom(-1) {
|
||||
memset(val,0,256*sizeof(int));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[i].state.alg][j]) {
|
||||
if (isOutputL[ops==4][chan[i].state.alg][j] || i>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[i].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -435,7 +435,7 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[i].state.alg][j]) {
|
||||
if (isOutputL[ops==4][chan[i].state.alg][j] || i>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[i].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -445,10 +445,34 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (i<melodicChans) {
|
||||
if (chan[i].hardReset && chan[i].keyOn) {
|
||||
for (int j=0; j<ops; j++) {
|
||||
unsigned char slot=slots[j][i];
|
||||
if (slot==255) continue;
|
||||
unsigned short baseAddr=slotMap[slot];
|
||||
DivInstrumentFM::Operator& op=chan[i].state.op[(ops==4)?orderedOpsL[j]:j];
|
||||
immWrite(baseAddr+ADDR_SL_RR,0x0f);
|
||||
immWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
oldWrites[baseAddr+ADDR_SL_RR]=-1;
|
||||
oldWrites[baseAddr+ADDR_KSL_TL]=-1;
|
||||
}
|
||||
}
|
||||
if (chan[i].keyOn || chan[i].keyOff) {
|
||||
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
||||
chan[i].keyOff=false;
|
||||
}
|
||||
if (chan[i].hardReset && chan[i].keyOn) {
|
||||
for (int j=0; j<ops; j++) {
|
||||
unsigned char slot=slots[j][i];
|
||||
if (slot==255) continue;
|
||||
unsigned short baseAddr=slotMap[slot];
|
||||
DivInstrumentFM::Operator& op=chan[i].state.op[(ops==4)?orderedOpsL[j]:j];
|
||||
for (int k=0; k<5; k++) {
|
||||
immWrite(baseAddr+ADDR_SL_RR,0x0f);
|
||||
immWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -579,7 +603,7 @@ void DivPlatformOPL::muteChannel(int ch, bool mute) {
|
|||
if (isMuted[ch]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[ch].state.alg][i]) {
|
||||
if (isOutputL[ops==4][chan[ch].state.alg][i] || ch>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[ch].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -634,7 +658,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][i]) {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][i] || c.chan>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -723,7 +747,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][i]) {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][i] || c.chan>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -856,7 +880,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][c.value]) {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][c.value] || c.chan>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -1076,7 +1100,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][i]) {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][i] || c.chan>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -1093,7 +1117,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][c.value]) {
|
||||
if (isOutputL[ops==4][chan[c.chan].state.alg][c.value] || c.chan>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[c.chan].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
@ -1118,6 +1142,9 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_HARD_RESET:
|
||||
chan[c.chan].hardReset=c.value;
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
break;
|
||||
|
|
@ -1161,7 +1188,7 @@ void DivPlatformOPL::forceIns() {
|
|||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,63|(op.ksl<<6));
|
||||
} else {
|
||||
if (isOutputL[ops==4][chan[i].state.alg][j]) {
|
||||
if (isOutputL[ops==4][chan[i].state.alg][j] || i>=melodicChans) {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,(63-(((63-op.tl)*(chan[i].outVol&0x3f))/63))|(op.ksl<<6));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_KSL_TL,op.tl|(op.ksl<<6));
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
DivMacroInt std;
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta, fourOp, hardReset;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
void macroInit(DivInstrument* which) {
|
||||
|
|
@ -56,6 +56,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
furnaceDac(false),
|
||||
inPorta(false),
|
||||
fourOp(false),
|
||||
hardReset(false),
|
||||
vol(0),
|
||||
pan(3) {
|
||||
state.ops=2;
|
||||
|
|
|
|||
|
|
@ -919,7 +919,6 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_FM_FIXFREQ: {
|
||||
if (c.value<0 || c.value>3) break;
|
||||
printf("fixfreq %x\n",c.value2);
|
||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||
op.egt=(c.value2>0);
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2612_EXT]=new DivSysDef(
|
||||
"Yamaha YM2612 Extended Channel 3", NULL, 0xa0, 0, 9, true, false, 0x150, false,
|
||||
"Yamaha YM2612 (OPN2) Extended Channel 3", NULL, 0xa0, 0, 9, true, false, 0x150, false,
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6"},
|
||||
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM},
|
||||
|
|
@ -1481,7 +1481,7 @@ void DivEngine::registerSystems() {
|
|||
};
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPL_DRUMS]=new DivSysDef(
|
||||
"Yamaha OPL with drums", NULL, 0xa2, 0, 11, true, false, 0x151, false,
|
||||
"Yamaha YM3526 (OPL) with drums", NULL, 0xa2, 0, 11, true, false, 0x151, false,
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
|
|
@ -1492,7 +1492,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPL2_DRUMS]=new DivSysDef(
|
||||
"Yamaha OPL2 with drums", NULL, 0xa3, 0, 11, true, false, 0x151, false,
|
||||
"Yamaha YM3812 (OPL2) with drums", NULL, 0xa3, 0, 11, true, false, 0x151, false,
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
|
|
@ -1503,7 +1503,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPL3_DRUMS]=new DivSysDef(
|
||||
"Yamaha OPL3 with drums", NULL, 0xa4, 0, 20, true, false, 0x151, false,
|
||||
"Yamaha YMF262 (OPL3) with drums", NULL, 0xa4, 0, 20, true, false, 0x151, false,
|
||||
{"4OP 1", "FM 2", "4OP 3", "FM 4", "4OP 5", "FM 6", "4OP 7", "FM 8", "4OP 9", "FM 10", "4OP 11", "FM 12", "FM 13", "FM 14", "FM 15", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
|
|
@ -1525,7 +1525,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2610_FULL_EXT]=new DivSysDef(
|
||||
"Yamaha YM2610 Extended Channel 2", NULL, 0xa6, 0, 17, true, false, 0x151, false,
|
||||
"Yamaha YM2610 (OPNB) Extended Channel 2", NULL, 0xa6, 0, 17, true, false, 0x151, false,
|
||||
{"FM 1", "FM 2 OP1", "FM 2 OP2", "FM 2 OP3", "FM 2 OP4", "FM 3", "FM 4", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"},
|
||||
{"F1", "O1", "O2", "O3", "O4", "F3", "F4", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"},
|
||||
{DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
|
|
@ -1536,7 +1536,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPLL_DRUMS]=new DivSysDef(
|
||||
"Yamaha OPLL with drums", NULL, 0xa7, 0, 11, true, false, 0x150, false,
|
||||
"Yamaha YM2413 (OPLL) with drums", NULL, 0xa7, 0, 11, true, false, 0x150, false,
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Kick", "Snare", "Tom", "Top", "HiHat"},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "BD", "SD", "TM", "TP", "HH"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE},
|
||||
|
|
@ -1617,7 +1617,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2610B_EXT]=new DivSysDef(
|
||||
"Yamaha YM2610B Extended Channel 3", NULL, 0xde, 0, 19, true, false, 0x151, false,
|
||||
"Yamaha YM2610B (OPNB-B) Extended Channel 3", NULL, 0xde, 0, 19, true, false, 0x151, false,
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"},
|
||||
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue