mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 15:03:01 +00:00
OPL: more work - still not there yet
This commit is contained in:
parent
03d2f87804
commit
ec007b4443
3 changed files with 77 additions and 47 deletions
|
@ -30,14 +30,14 @@
|
|||
// N = invalid
|
||||
#define N 255
|
||||
|
||||
const unsigned char slotsOPL2[4][20]={
|
||||
const unsigned char slotsOPL2i[4][20]={
|
||||
{0, 1, 2, 6, 7, 8, 12, 13, 14}, // OP1
|
||||
{3, 4, 5, 9, 10, 11, 15, 16, 17}, // OP2
|
||||
{N, N, N, N, N, N, N, N, N},
|
||||
{N, N, N, N, N, N, N, N, N}
|
||||
};
|
||||
|
||||
const unsigned char slotsOPL2Drums[4][20]={
|
||||
const unsigned char slotsOPL2Drumsi[4][20]={
|
||||
{0, 1, 2, 6, 7, 8, 12, 16, 14, 17, 13}, // OP1
|
||||
{3, 4, 5, 9, 10, 11, 15, N, N, N, N}, // OP2
|
||||
{N, N, N, N, N, N, N, N, N, N, N},
|
||||
|
@ -48,14 +48,28 @@ 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
|
||||
};
|
||||
|
||||
const unsigned char slotsOPL3[4][20]={
|
||||
const unsigned char* slotsOPL2[4]={
|
||||
slotsOPL2i[0],
|
||||
slotsOPL2i[1],
|
||||
slotsOPL2i[2],
|
||||
slotsOPL2i[3]
|
||||
};
|
||||
|
||||
const unsigned char* slotsOPL2Drums[4]={
|
||||
slotsOPL2Drumsi[0],
|
||||
slotsOPL2Drumsi[1],
|
||||
slotsOPL2Drumsi[2],
|
||||
slotsOPL2Drumsi[3]
|
||||
};
|
||||
|
||||
const unsigned char slotsOPL3i[4][20]={
|
||||
{0, 6, 1, 7, 2, 8, 18, 24, 19, 25, 20, 26, 30, 31, 32, 12, 13, 14}, // OP1
|
||||
{3, 9, 4, 10, 5, 11, 21, 27, 22, 28, 23, 29, 33, 34, 35, 15, 16, 17}, // OP2
|
||||
{6, N, 7, N, 8, N, 24, N, 25, N, 26, 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} // OP4
|
||||
};
|
||||
|
||||
const unsigned char slotsOPL3Drums[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
|
||||
{3, 9, 4, 10, 5, 11, 21, 27, 22, 28, 23, 29, 33, 34, 35, N, 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
|
||||
|
@ -66,6 +80,20 @@ 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
|
||||
};
|
||||
|
||||
const unsigned char* slotsOPL3[4]={
|
||||
slotsOPL3i[0],
|
||||
slotsOPL3i[1],
|
||||
slotsOPL3i[2],
|
||||
slotsOPL3i[3]
|
||||
};
|
||||
|
||||
const unsigned char* slotsOPL3Drums[4]={
|
||||
slotsOPL3Drumsi[0],
|
||||
slotsOPL3Drumsi[1],
|
||||
slotsOPL3Drumsi[2],
|
||||
slotsOPL3Drumsi[3]
|
||||
};
|
||||
|
||||
const unsigned int slotMap[36]={
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
|
@ -167,18 +195,8 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
if (!writes.empty() && --delay<0) {
|
||||
delay=12;
|
||||
QueuedWrite& w=writes.front();
|
||||
if (w.addrOrVal) {
|
||||
OPL3_WriteReg(&fm,0x1+((w.addr>>8)<<1),w.val);
|
||||
//printf("write: %x = %.2x\n",w.addr,w.val);
|
||||
lastBusy=0;
|
||||
regPool[w.addr&0x1ff]=w.val;
|
||||
writes.pop();
|
||||
} else {
|
||||
lastBusy++;
|
||||
//printf("busycounter: %d\n",lastBusy);
|
||||
OPL3_WriteReg(&fm,0x0+((w.addr>>8)<<1),w.addr);
|
||||
w.addrOrVal=true;
|
||||
}
|
||||
OPL3_WriteReg(&fm,w.addr,w.val);
|
||||
writes.pop();
|
||||
}
|
||||
|
||||
OPL3_Generate(&fm,o); os[0]+=o[0]; os[1]+=o[1];
|
||||
|
@ -203,11 +221,10 @@ void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
}
|
||||
|
||||
void DivPlatformOPL::tick() {
|
||||
/*
|
||||
for (int i=0; i<20; i++) {
|
||||
if (i==2 && extMode) continue;
|
||||
chan[i].std.next();
|
||||
|
||||
/*
|
||||
if (chan[i].std.hadVol) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(127,chan[i].std.vol))/127;
|
||||
for (int j=0; j<4; j++) {
|
||||
|
@ -327,13 +344,13 @@ void DivPlatformOPL::tick() {
|
|||
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (chan[i].keyOn || chan[i].keyOff) {
|
||||
immWrite(0x28,0x00|konOffs[i]);
|
||||
immWrite(chanMap[i]+ADDR_FREQH,0x00|(chan[i].freqH&31));
|
||||
chan[i].keyOff=false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
for (int i=0; i<512; i++) {
|
||||
if (pendingWrites[i]!=oldWrites[i]) {
|
||||
|
@ -342,36 +359,23 @@ void DivPlatformOPL::tick() {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i=0; i<20; i++) {
|
||||
if (chan[i].freqChanged) {
|
||||
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);
|
||||
immWrite(chanOffs[i]+ADDR_FREQH,freqt>>8);
|
||||
immWrite(chanOffs[i]+ADDR_FREQ,freqt&0xff);
|
||||
if (chan[i].furnaceDac && dacMode) {
|
||||
double off=1.0;
|
||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
if (s->centerRate<1) {
|
||||
off=1.0;
|
||||
} else {
|
||||
off=8363.0/(double)s->centerRate;
|
||||
}
|
||||
}
|
||||
dacRate=(1280000*1.25*off)/MAX(1,chan[i].baseFreq);
|
||||
if (dacRate<1) dacRate=1;
|
||||
if (dumpWrites) addWrite(0xffff0001,1280000/dacRate);
|
||||
}
|
||||
chan[i].freqChanged=false;
|
||||
chan[i].freqH=freqt>>8;
|
||||
chan[i].freqL=freqt&0xff;
|
||||
immWrite(chanMap[i]+ADDR_FREQ,chan[i].freqL);
|
||||
}
|
||||
if (chan[i].keyOn) {
|
||||
immWrite(0x28,0xf0|konOffs[i]);
|
||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(0x20));
|
||||
chan[i].keyOn=false;
|
||||
} else if (chan[i].freqChanged) {
|
||||
immWrite(chanMap[i]+ADDR_FREQH,chan[i].freqH|(chan[i].active<<5));
|
||||
}
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int DivPlatformOPL::octave(int freq) {
|
||||
|
@ -395,6 +399,7 @@ int DivPlatformOPL::octave(int freq) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
int DivPlatformOPL::toFreq(int freq) {
|
||||
if (freq>=82432) {
|
||||
return 0x3800|((freq>>7)&0x7ff);
|
||||
|
@ -659,7 +664,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
return 0;
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 127;
|
||||
return 63;
|
||||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
chan[c.chan].inPorta=c.value;
|
||||
|
@ -801,14 +806,14 @@ void DivPlatformOPL::setYMFM(bool use) {
|
|||
void DivPlatformOPL::setOPLType(int type, bool drums) {
|
||||
switch (type) {
|
||||
case 1: case 2:
|
||||
slotsNonDrums=(const unsigned char**)slotsOPL2;
|
||||
slotsDrums=(const unsigned char**)slotsOPL2Drums;
|
||||
slotsNonDrums=slotsOPL2;
|
||||
slotsDrums=slotsOPL2Drums;
|
||||
slots=drums?slotsDrums:slotsNonDrums;
|
||||
chanMap=chanMapOPL2;
|
||||
break;
|
||||
case 3:
|
||||
slotsNonDrums=(const unsigned char**)slotsOPL3;
|
||||
slotsDrums=(const unsigned char**)slotsOPL3Drums;
|
||||
slotsNonDrums=slotsOPL3;
|
||||
slotsDrums=slotsOPL3Drums;
|
||||
slots=drums?slotsDrums:slotsNonDrums;
|
||||
chanMap=chanMapOPL3;
|
||||
break;
|
||||
|
|
|
@ -4629,6 +4629,12 @@ bool FurnaceGUI::loop() {
|
|||
sysAddOption(DIV_SYSTEM_OPLL);
|
||||
sysAddOption(DIV_SYSTEM_OPLL_DRUMS);
|
||||
sysAddOption(DIV_SYSTEM_VRC7);
|
||||
sysAddOption(DIV_SYSTEM_OPL);
|
||||
sysAddOption(DIV_SYSTEM_OPL_DRUMS);
|
||||
sysAddOption(DIV_SYSTEM_OPL2);
|
||||
sysAddOption(DIV_SYSTEM_OPL2_DRUMS);
|
||||
sysAddOption(DIV_SYSTEM_OPL3);
|
||||
sysAddOption(DIV_SYSTEM_OPL3_DRUMS);
|
||||
sysAddOption(DIV_SYSTEM_TIA);
|
||||
sysAddOption(DIV_SYSTEM_SAA1099);
|
||||
sysAddOption(DIV_SYSTEM_AY8930);
|
||||
|
@ -4974,6 +4980,12 @@ bool FurnaceGUI::loop() {
|
|||
sysChangeOption(i,DIV_SYSTEM_OPLL);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPLL_DRUMS);
|
||||
sysChangeOption(i,DIV_SYSTEM_VRC7);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPL);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPL_DRUMS);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPL2);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPL2_DRUMS);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPL3);
|
||||
sysChangeOption(i,DIV_SYSTEM_OPL3_DRUMS);
|
||||
sysChangeOption(i,DIV_SYSTEM_TIA);
|
||||
sysChangeOption(i,DIV_SYSTEM_SAA1099);
|
||||
sysChangeOption(i,DIV_SYSTEM_AY8930);
|
||||
|
|
|
@ -796,7 +796,8 @@ void FurnaceGUI::drawInsEdit() {
|
|||
int asInt[256];
|
||||
float loopIndicator[256];
|
||||
int opCount=4;
|
||||
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL) opCount=2;
|
||||
if (ins->type==DIV_INS_OPLL) opCount=2;
|
||||
if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2;
|
||||
|
||||
if (ImGui::BeginTabItem("FM")) {
|
||||
if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) {
|
||||
|
@ -816,7 +817,19 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::TableNextColumn();
|
||||
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
||||
break;
|
||||
case DIV_INS_OPL:
|
||||
case DIV_INS_OPL: {
|
||||
bool fourOp=(ins->fm.ops==4);
|
||||
ImGui::TableNextColumn();
|
||||
P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
|
||||
if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER
|
||||
ins->fm.ops=fourOp?4:2;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
P(ImGui::SliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable
|
||||
ImGui::TableNextColumn();
|
||||
drawAlgorithm(ins->fm.alg&1,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
||||
break;
|
||||
}
|
||||
case DIV_INS_OPLL: {
|
||||
bool dc=ins->fm.fms;
|
||||
bool dm=ins->fm.ams;
|
||||
|
|
Loading…
Reference in a new issue