mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-18 02:25:11 +00:00
port ExtCh op macro code to OPN family, part 1
This commit is contained in:
parent
44b90b6a10
commit
2a65f24b3f
4 changed files with 152 additions and 27 deletions
|
@ -42,14 +42,31 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||||
|
|
||||||
|
if (opChan[ch].insChanged) {
|
||||||
|
chan[2].state.alg=ins->fm.alg;
|
||||||
|
chan[2].state.fb=ins->fm.fb;
|
||||||
|
chan[2].state.fms=ins->fm.fms;
|
||||||
|
chan[2].state.ams=ins->fm.ams;
|
||||||
|
chan[2].state.op[ordch]=ins->fm.op[ordch];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noExtMacros) {
|
||||||
|
opChan[ch].macroInit(NULL);
|
||||||
|
} else {
|
||||||
|
opChan[ch].macroInit(ins);
|
||||||
|
}
|
||||||
|
if (!opChan[ch].std.vol.will) {
|
||||||
|
opChan[ch].outVol=opChan[ch].vol;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[2].state.op[ordch];
|
||||||
// TODO: how does this work?!
|
// TODO: how does this work?!
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
|
@ -62,13 +79,15 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
|
||||||
opChan[ch].mask=op.enable;
|
opChan[ch].mask=op.enable;
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) { // TODO how does this work?
|
if (opChan[ch].insChanged) { // TODO how does this work?
|
||||||
rWrite(chanOffs[2]+0xb0,(ins->fm.alg&7)|(ins->fm.fb<<3));
|
rWrite(chanOffs[2]+0xb0,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
|
||||||
|
rWrite(chanOffs[2]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[2].state.fms&7)|((chan[2].state.ams&3)<<4));
|
||||||
}
|
}
|
||||||
opChan[ch].insChanged=false;
|
opChan[ch].insChanged=false;
|
||||||
|
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
||||||
opChan[ch].portaPause=false;
|
opChan[ch].portaPause=false;
|
||||||
|
opChan[ch].note=c.value;
|
||||||
opChan[ch].freqChanged=true;
|
opChan[ch].freqChanged=true;
|
||||||
}
|
}
|
||||||
opChan[ch].keyOn=true;
|
opChan[ch].keyOn=true;
|
||||||
|
@ -80,15 +99,28 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) {
|
||||||
opChan[ch].keyOn=false;
|
opChan[ch].keyOn=false;
|
||||||
opChan[ch].active=false;
|
opChan[ch].active=false;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].keyOff=true;
|
||||||
|
opChan[ch].keyOn=false;
|
||||||
|
opChan[ch].active=false;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
|
case DIV_CMD_ENV_RELEASE:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
case DIV_CMD_VOLUME: {
|
case DIV_CMD_VOLUME: {
|
||||||
opChan[ch].vol=c.value;
|
opChan[ch].vol=c.value;
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
if (!opChan[ch].std.vol.has) {
|
||||||
|
opChan[ch].outVol=c.value;
|
||||||
|
}
|
||||||
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[2].state.op[ordch];
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,14 +42,31 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||||
|
|
||||||
|
if (opChan[ch].insChanged) {
|
||||||
|
chan[2].state.alg=ins->fm.alg;
|
||||||
|
chan[2].state.fb=ins->fm.fb;
|
||||||
|
chan[2].state.fms=ins->fm.fms;
|
||||||
|
chan[2].state.ams=ins->fm.ams;
|
||||||
|
chan[2].state.op[ordch]=ins->fm.op[ordch];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noExtMacros) {
|
||||||
|
opChan[ch].macroInit(NULL);
|
||||||
|
} else {
|
||||||
|
opChan[ch].macroInit(ins);
|
||||||
|
}
|
||||||
|
if (!opChan[ch].std.vol.will) {
|
||||||
|
opChan[ch].outVol=opChan[ch].vol;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[2].state.op[ordch];
|
||||||
// TODO: how does this work?!
|
// TODO: how does this work?!
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
|
@ -62,14 +79,15 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
|
||||||
opChan[ch].mask=op.enable;
|
opChan[ch].mask=op.enable;
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) { // TODO how does this work?
|
if (opChan[ch].insChanged) { // TODO how does this work?
|
||||||
rWrite(chanOffs[2]+0xb0,(ins->fm.alg&7)|(ins->fm.fb<<3));
|
rWrite(chanOffs[2]+0xb0,(chan[2].state.alg&7)|(chan[2].state.fb<<3));
|
||||||
rWrite(chanOffs[2]+0xb4,(opChan[ch].pan<<6)|(ins->fm.fms&7)|((ins->fm.ams&3)<<4));
|
rWrite(chanOffs[2]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[2].state.fms&7)|((chan[2].state.ams&3)<<4));
|
||||||
}
|
}
|
||||||
opChan[ch].insChanged=false;
|
opChan[ch].insChanged=false;
|
||||||
|
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
||||||
opChan[ch].portaPause=false;
|
opChan[ch].portaPause=false;
|
||||||
|
opChan[ch].note=c.value;
|
||||||
opChan[ch].freqChanged=true;
|
opChan[ch].freqChanged=true;
|
||||||
}
|
}
|
||||||
opChan[ch].keyOn=true;
|
opChan[ch].keyOn=true;
|
||||||
|
@ -81,15 +99,28 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) {
|
||||||
opChan[ch].keyOn=false;
|
opChan[ch].keyOn=false;
|
||||||
opChan[ch].active=false;
|
opChan[ch].active=false;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].keyOff=true;
|
||||||
|
opChan[ch].keyOn=false;
|
||||||
|
opChan[ch].active=false;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
|
case DIV_CMD_ENV_RELEASE:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
case DIV_CMD_VOLUME: {
|
case DIV_CMD_VOLUME: {
|
||||||
opChan[ch].vol=c.value;
|
opChan[ch].vol=c.value;
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
if (!opChan[ch].std.vol.has) {
|
||||||
|
opChan[ch].outVol=c.value;
|
||||||
|
}
|
||||||
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[2]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[2].state.op[ordch];
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,31 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||||
|
|
||||||
|
if (opChan[ch].insChanged) {
|
||||||
|
chan[extChanOffs].state.alg=ins->fm.alg;
|
||||||
|
chan[extChanOffs].state.fb=ins->fm.fb;
|
||||||
|
chan[extChanOffs].state.fms=ins->fm.fms;
|
||||||
|
chan[extChanOffs].state.ams=ins->fm.ams;
|
||||||
|
chan[extChanOffs].state.op[ordch]=ins->fm.op[ordch];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noExtMacros) {
|
||||||
|
opChan[ch].macroInit(NULL);
|
||||||
|
} else {
|
||||||
|
opChan[ch].macroInit(ins);
|
||||||
|
}
|
||||||
|
if (!opChan[ch].std.vol.will) {
|
||||||
|
opChan[ch].outVol=opChan[ch].vol;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[ordch];
|
||||||
// TODO: how does this work?!
|
// TODO: how does this work?!
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
|
@ -58,14 +75,15 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
|
||||||
opChan[ch].mask=op.enable;
|
opChan[ch].mask=op.enable;
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) { // TODO how does this work?
|
if (opChan[ch].insChanged) { // TODO how does this work?
|
||||||
rWrite(chanOffs[extChanOffs]+0xb0,(ins->fm.alg&7)|(ins->fm.fb<<3));
|
rWrite(chanOffs[extChanOffs]+0xb0,(chan[extChanOffs].state.alg&7)|(chan[extChanOffs].state.fb<<3));
|
||||||
rWrite(chanOffs[extChanOffs]+0xb4,(opChan[ch].pan<<6)|(ins->fm.fms&7)|((ins->fm.ams&3)<<4));
|
rWrite(chanOffs[extChanOffs]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[extChanOffs].state.fms&7)|((chan[extChanOffs].state.ams&3)<<4));
|
||||||
}
|
}
|
||||||
opChan[ch].insChanged=false;
|
opChan[ch].insChanged=false;
|
||||||
|
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
||||||
opChan[ch].portaPause=false;
|
opChan[ch].portaPause=false;
|
||||||
|
opChan[ch].note=c.value;
|
||||||
opChan[ch].freqChanged=true;
|
opChan[ch].freqChanged=true;
|
||||||
}
|
}
|
||||||
opChan[ch].keyOn=true;
|
opChan[ch].keyOn=true;
|
||||||
|
@ -77,15 +95,28 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
|
||||||
opChan[ch].keyOn=false;
|
opChan[ch].keyOn=false;
|
||||||
opChan[ch].active=false;
|
opChan[ch].active=false;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].keyOff=true;
|
||||||
|
opChan[ch].keyOn=false;
|
||||||
|
opChan[ch].active=false;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
|
case DIV_CMD_ENV_RELEASE:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
case DIV_CMD_VOLUME: {
|
case DIV_CMD_VOLUME: {
|
||||||
opChan[ch].vol=c.value;
|
opChan[ch].vol=c.value;
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
if (!opChan[ch].std.vol.has) {
|
||||||
|
opChan[ch].outVol=c.value;
|
||||||
|
}
|
||||||
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[ordch];
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,31 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
||||||
|
|
||||||
|
if (opChan[ch].insChanged) {
|
||||||
|
chan[extChanOffs].state.alg=ins->fm.alg;
|
||||||
|
chan[extChanOffs].state.fb=ins->fm.fb;
|
||||||
|
chan[extChanOffs].state.fms=ins->fm.fms;
|
||||||
|
chan[extChanOffs].state.ams=ins->fm.ams;
|
||||||
|
chan[extChanOffs].state.op[ordch]=ins->fm.op[ordch];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noExtMacros) {
|
||||||
|
opChan[ch].macroInit(NULL);
|
||||||
|
} else {
|
||||||
|
opChan[ch].macroInit(ins);
|
||||||
|
}
|
||||||
|
if (!opChan[ch].std.vol.will) {
|
||||||
|
opChan[ch].outVol=opChan[ch].vol;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[ordch];
|
||||||
// TODO: how does this work?!
|
// TODO: how does this work?!
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) {
|
if (opChan[ch].insChanged) {
|
||||||
|
@ -58,14 +75,15 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
||||||
opChan[ch].mask=op.enable;
|
opChan[ch].mask=op.enable;
|
||||||
}
|
}
|
||||||
if (opChan[ch].insChanged) { // TODO how does this work?
|
if (opChan[ch].insChanged) { // TODO how does this work?
|
||||||
rWrite(chanOffs[extChanOffs]+0xb0,(ins->fm.alg&7)|(ins->fm.fb<<3));
|
rWrite(chanOffs[extChanOffs]+0xb0,(chan[extChanOffs].state.alg&7)|(chan[extChanOffs].state.fb<<3));
|
||||||
rWrite(chanOffs[extChanOffs]+0xb4,(opChan[ch].pan<<6)|(ins->fm.fms&7)|((ins->fm.ams&3)<<4));
|
rWrite(chanOffs[extChanOffs]+0xb4,(IS_EXTCH_MUTED?0:(opChan[ch].pan<<6))|(chan[extChanOffs].state.fms&7)|((chan[extChanOffs].state.ams&3)<<4));
|
||||||
}
|
}
|
||||||
opChan[ch].insChanged=false;
|
opChan[ch].insChanged=false;
|
||||||
|
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
opChan[ch].baseFreq=NOTE_FNUM_BLOCK(c.value,11);
|
||||||
opChan[ch].portaPause=false;
|
opChan[ch].portaPause=false;
|
||||||
|
opChan[ch].note=c.value;
|
||||||
opChan[ch].freqChanged=true;
|
opChan[ch].freqChanged=true;
|
||||||
}
|
}
|
||||||
opChan[ch].keyOn=true;
|
opChan[ch].keyOn=true;
|
||||||
|
@ -77,15 +95,28 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
||||||
opChan[ch].keyOn=false;
|
opChan[ch].keyOn=false;
|
||||||
opChan[ch].active=false;
|
opChan[ch].active=false;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].keyOff=true;
|
||||||
|
opChan[ch].keyOn=false;
|
||||||
|
opChan[ch].active=false;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
|
case DIV_CMD_ENV_RELEASE:
|
||||||
|
if (noExtMacros) break;
|
||||||
|
opChan[ch].std.release();
|
||||||
|
break;
|
||||||
case DIV_CMD_VOLUME: {
|
case DIV_CMD_VOLUME: {
|
||||||
opChan[ch].vol=c.value;
|
opChan[ch].vol=c.value;
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
if (!opChan[ch].std.vol.has) {
|
||||||
|
opChan[ch].outVol=c.value;
|
||||||
|
}
|
||||||
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
unsigned short baseAddr=chanOffs[extChanOffs]|opOffs[ordch];
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[ordch];
|
DivInstrumentFM::Operator& op=chan[extChanOffs].state.op[ordch];
|
||||||
if (isOpMuted[ch]) {
|
if (isOpMuted[ch]) {
|
||||||
rWrite(baseAddr+0x40,127);
|
rWrite(baseAddr+0x40,127);
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].vol&0x7f,127));
|
rWrite(baseAddr+0x40,127-VOL_SCALE_LOG_BROKEN(127-op.tl,opChan[ch].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue