redo opnx csm

This commit is contained in:
Eknous-P 2024-10-09 17:28:58 +04:00 committed by tildearrow
parent 901bb110cc
commit 5f47166012
17 changed files with 572 additions and 147 deletions

View file

@ -237,8 +237,8 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767);
}
for (int i=3; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2]<<1;
for (int i=(3+isCSM); i<(6+isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2+isCSM]<<1;
}
}
}
@ -290,8 +290,8 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) {
oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767);
}
for (int i=3; i<6; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2]<<1;
for (int i=(3+isCSM); i<(6+isCSM); i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-2+isCSM]<<1;
}
}
}
@ -723,15 +723,29 @@ void DivPlatformYM2203::commitState(int ch, DivInstrument* ins) {
}
int DivPlatformYM2203::dispatch(DivCommand c) {
if (c.chan>2) {
c.chan-=3;
if (c.chan>(2+isCSM)) {
c.chan-=(3+isCSM);
return ay->dispatch(c);
}
switch (c.cmd) {
case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
if (c.chan==csmChan && extMode) { // CSM
chan[c.chan].macroInit(ins);
chan[c.chan].insChanged=false;
if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
chan[c.chan].portaPause=false;
chan[c.chan].note=c.value;
chan[c.chan].freqChanged=true;
}
chan[c.chan].keyOn=true;
chan[c.chan].active=true;
break;
}
chan[c.chan].macroInit(ins);
if (c.chan<3) {
if (c.chan<psgChanOffs) {
if (!chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
}
@ -801,7 +815,30 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
break;
}
case DIV_CMD_NOTE_PORTA: {
if (c.chan>2 || parent->song.linearPitch==2) { // PSG
if (c.chan==csmChan) {
int destFreq=NOTE_PERIODIC(c.value2);
bool return2=false;
if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value;
if (chan[c.chan].baseFreq>=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
} else {
chan[c.chan].baseFreq-=c.value;
if (chan[c.chan].baseFreq<=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
}
chan[c.chan].freqChanged=true;
if (return2) {
chan[c.chan].inPorta=false;
return 2;
}
break;
}
if (c.chan>(psgChanOffs-1) || parent->song.linearPitch==2) { // PSG
int destFreq=NOTE_FNUM_BLOCK(c.value2,11);
bool return2=false;
if (destFreq>chan[c.chan].baseFreq) {
@ -828,6 +865,9 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
break;
}
case DIV_CMD_LEGATO: {
if (c.chan==csmChan) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
}
if (chan[c.chan].insChanged) {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
commitState(c.chan,ins);
@ -1053,11 +1093,11 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
chan[c.chan].std.restart(c.value);
break;
case DIV_CMD_GET_VOLMAX:
if (c.chan>2) return 15;
if (c.chan>(2+isCSM)) return 15;
return 127;
break;
case DIV_CMD_PRE_PORTA:
if (c.chan>2) {
if (c.chan>(2+isCSM)) {
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_FM));
}
@ -1075,8 +1115,8 @@ int DivPlatformYM2203::dispatch(DivCommand c) {
void DivPlatformYM2203::muteChannel(int ch, bool mute) {
isMuted[ch]=mute;
if (ch>2) { // PSG
ay->muteChannel(ch-3,mute);
if (ch>(2+isCSM)) { // PSG
ay->muteChannel(ch-(3+isCSM),mute);
return;
}
for (int j=0; j<4; j++) {
@ -1121,7 +1161,7 @@ void DivPlatformYM2203::forceIns() {
chan[i].freqChanged=true;
}
}
for (int i=3; i<6; i++) {
for (int i=(3+isCSM); i<(6+isCSM); i++) {
chan[i].insChanged=true;
}
@ -1139,7 +1179,7 @@ void* DivPlatformYM2203::getChanState(int ch) {
}
DivMacroInt* DivPlatformYM2203::getChanMacroInt(int ch) {
if (ch>=3) return ay->getChanMacroInt(ch-3);
if (ch>=(3+isCSM)) return ay->getChanMacroInt(ch-(3+isCSM));
return &chan[ch].std;
}
@ -1173,15 +1213,15 @@ void DivPlatformYM2203::reset() {
OPN2_SetChipType(&fm_nuked,ym3438_mode_opn);
fm->reset();
memset(&fm_lle,0,sizeof(fmopna_t));
for (int i=0; i<6; i++) {
for (int i=0; i<7; i++) {
chan[i]=DivPlatformOPN::OPNChannel();
chan[i].std.setEngine(parent);
}
for (int i=0; i<3; i++) {
for (int i=0; i<3; i++) { // check back later / me from future: wha?
chan[i].vol=0x7f;
chan[i].outVol=0x7f;
}
for (int i=3; i<6; i++) {
for (int i=(3+isCSM); i<(6+isCSM); i++) {
chan[i].vol=0x0f;
}
@ -1255,7 +1295,7 @@ bool DivPlatformYM2203::keyOffAffectsArp(int ch) {
}
void DivPlatformYM2203::notifyInsChange(int ins) {
for (int i=0; i<6; i++) {
for (int i=0; i<7; i++) {
if (chan[i].ins==ins) {
chan[i].insChanged=true;
}
@ -1331,7 +1371,7 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) {
} else {
rate=fm->sample_rate(chipClock);
}
for (int i=0; i<6; i++) {
for (int i=0; i<7; i++) {
oscBuf[i]->rate=rate;
}
immWrite(0x2d,0xff);
@ -1345,7 +1385,7 @@ int DivPlatformYM2203::init(DivEngine* p, int channels, int sugRate, const DivCo
parent=p;
dumpWrites=false;
skipRegisterWrites=false;
for (int i=0; i<6; i++) {
for (int i=0; i<7; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
@ -1358,11 +1398,11 @@ int DivPlatformYM2203::init(DivEngine* p, int channels, int sugRate, const DivCo
setFlags(flags);
reset();
return 6;
return 7;
}
void DivPlatformYM2203::quit() {
for (int i=0; i<6; i++) {
for (int i=0; i<7; i++) {
delete oscBuf[i];
}
ay->quit();