implement KVS on YM2612
This commit is contained in:
parent
9685a5c0d8
commit
ac68419b78
4
TODO.md
4
TODO.md
|
@ -1,5 +1 @@
|
||||||
# to-do for 0.6pre1.5
|
|
||||||
|
|
||||||
- stereo separation control for AY
|
|
||||||
- KVS
|
|
||||||
- bug fixes
|
|
||||||
|
|
|
@ -196,6 +196,15 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Genesis detuned on Defle v10 and earlier
|
||||||
|
/*if (ds.version<19 && ds.system[0]==DIV_SYSTEM_GENESIS) {
|
||||||
|
ds.tuning=443.23;
|
||||||
|
}*/
|
||||||
|
// C64 detuned on Defle v11 and earlier
|
||||||
|
/*if (ds.version<21 && (ds.system[0]==DIV_SYSTEM_C64_6581 || ds.system[0]==DIV_SYSTEM_C64_8580)) {
|
||||||
|
ds.tuning=433.2;
|
||||||
|
}*/
|
||||||
|
|
||||||
logI("reading module data...");
|
logI("reading module data...");
|
||||||
if (ds.version>0x0c) {
|
if (ds.version>0x0c) {
|
||||||
ds.subsong[0]->hilightA=reader.readC();
|
ds.subsong[0]->hilightA=reader.readC();
|
||||||
|
@ -449,6 +458,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->fm.op[j].ssgEnv=reader.readC();
|
ins->fm.op[j].ssgEnv=reader.readC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ds.version<0x12) { // before version 10 all ops were responsive to volume
|
||||||
|
ins->fm.op[j].kvs=1;
|
||||||
|
}
|
||||||
|
|
||||||
logD("OP%d: AM %d AR %d DAM %d DR %d DVB %d EGT %d KSL %d MULT %d RR %d SL %d SUS %d TL %d VIB %d WS %d RS %d DT %d D2R %d SSG-EG %d",j,
|
logD("OP%d: AM %d AR %d DAM %d DR %d DVB %d EGT %d KSL %d MULT %d RR %d SL %d SUS %d TL %d VIB %d WS %d RS %d DT %d D2R %d SSG-EG %d",j,
|
||||||
ins->fm.op[j].am,
|
ins->fm.op[j].am,
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "../dispatch.h"
|
#include "../dispatch.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
#define KVS(x,y) ((chan[x].state.op[y].kvs==2 && isOutput[chan[x].state.alg][y]) || chan[x].state.op[y].kvs==1)
|
||||||
|
|
||||||
class DivPlatformFMBase: public DivDispatch {
|
class DivPlatformFMBase: public DivDispatch {
|
||||||
protected:
|
protected:
|
||||||
const bool isOutput[8][4]={
|
const bool isOutput[8][4]={
|
||||||
|
|
|
@ -254,7 +254,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
||||||
if (isMuted[i]) {
|
if (isMuted[i]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[i].state.alg][j]) {
|
if (KVS(i,j)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
@ -327,7 +327,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
||||||
if (isMuted[i]) {
|
if (isMuted[i]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[i].state.alg][j]) {
|
if (KVS(i,j)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
@ -384,7 +384,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
||||||
if (isMuted[i]) {
|
if (isMuted[i]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[i].state.alg][j]) {
|
if (KVS(i,j)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
@ -501,7 +501,7 @@ void DivPlatformGenesis::muteChannel(int ch, bool mute) {
|
||||||
if (isMuted[ch]) {
|
if (isMuted[ch]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[ch].state.alg][j]) {
|
if (KVS(ch,j)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[ch].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[ch].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
@ -614,7 +614,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
if (isMuted[c.chan]) {
|
if (isMuted[c.chan]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[c.chan].state.alg][i]) {
|
if (KVS(c.chan,i)) {
|
||||||
if (!chan[c.chan].active || chan[c.chan].insChanged) {
|
if (!chan[c.chan].active || chan[c.chan].insChanged) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
if (isMuted[c.chan]) {
|
if (isMuted[c.chan]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[c.chan].state.alg][i]) {
|
if (KVS(c.chan,i)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
@ -860,7 +860,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
if (isMuted[c.chan]) {
|
if (isMuted[c.chan]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[c.chan].state.alg][c.value]) {
|
if (KVS(c.chan,c.value)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[c.chan].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
@ -1051,7 +1051,7 @@ void DivPlatformGenesis::forceIns() {
|
||||||
if (isMuted[i]) {
|
if (isMuted[i]) {
|
||||||
rWrite(baseAddr+ADDR_TL,127);
|
rWrite(baseAddr+ADDR_TL,127);
|
||||||
} else {
|
} else {
|
||||||
if (isOutput[chan[i].state.alg][j]) {
|
if (KVS(i,j)) {
|
||||||
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
rWrite(baseAddr+ADDR_TL,127-VOL_SCALE_LOG(127-op.tl,chan[i].outVol&0x7f,127));
|
||||||
} else {
|
} else {
|
||||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||||
|
|
|
@ -1603,6 +1603,7 @@ class FurnaceGUI {
|
||||||
void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, const ImVec2& size, unsigned short instType);
|
void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, const ImVec2& size, unsigned short instType);
|
||||||
void drawGBEnv(unsigned char vol, unsigned char len, unsigned char sLen, bool dir, const ImVec2& size);
|
void drawGBEnv(unsigned char vol, unsigned char len, unsigned char sLen, bool dir, const ImVec2& size);
|
||||||
void drawSysConf(int chan, DivSystem type, unsigned int& flags, bool modifyOnChange);
|
void drawSysConf(int chan, DivSystem type, unsigned int& flags, bool modifyOnChange);
|
||||||
|
void kvsConfig(DivInstrument* ins);
|
||||||
|
|
||||||
// these ones offer ctrl-wheel fine value changes.
|
// these ones offer ctrl-wheel fine value changes.
|
||||||
bool CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0);
|
bool CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0);
|
||||||
|
|
|
@ -1211,6 +1211,46 @@ inline bool enBit30(const int val) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FurnaceGUI::kvsConfig(DivInstrument* ins) {
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("(click to configure KVS)");
|
||||||
|
}
|
||||||
|
int opCount=4;
|
||||||
|
if (ins->type==DIV_INS_OPLL) opCount=2;
|
||||||
|
if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2;
|
||||||
|
if (ImGui::BeginPopupContextItem("IKVSOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||||
|
ImGui::Text("operator level changes with volume?");
|
||||||
|
if (ImGui::BeginTable("KVSTable",4,ImGuiTableFlags_BordersInner)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
int o=(opCount==4)?orderedOps[i]:i;
|
||||||
|
if (!(i&1)) ImGui::TableNextRow();
|
||||||
|
const char* label="AUTO##OPKVS";
|
||||||
|
if (ins->fm.op[o].kvs==0) {
|
||||||
|
label="NO##OPKVS";
|
||||||
|
} else if (ins->fm.op[o].kvs==1) {
|
||||||
|
label="YES##OPKVS";
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%d",i+1);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::PushID(o);
|
||||||
|
if (ImGui::Button(label,ImVec2(ImGui::GetContentRegionAvail().x,0.0f))) {
|
||||||
|
if (++ins->fm.op[o].kvs>2) ins->fm.op[o].kvs=0;
|
||||||
|
PARAMETER;
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
float asFloat[256];
|
float asFloat[256];
|
||||||
int asInt[256];
|
int asInt[256];
|
||||||
|
@ -1769,6 +1809,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable
|
P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
||||||
|
kvsConfig(ins);
|
||||||
break;
|
break;
|
||||||
case DIV_INS_OPZ:
|
case DIV_INS_OPZ:
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
@ -1781,6 +1822,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable
|
P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
||||||
|
kvsConfig(ins);
|
||||||
|
|
||||||
if (ImGui::Button("Request from TX81Z")) {
|
if (ImGui::Button("Request from TX81Z")) {
|
||||||
doAction(GUI_ACTION_TX81Z_REQUEST);
|
doAction(GUI_ACTION_TX81Z_REQUEST);
|
||||||
}
|
}
|
||||||
|
@ -1813,6 +1856,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
}
|
}
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
|
||||||
|
kvsConfig(ins);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_INS_OPLL: {
|
case DIV_INS_OPLL: {
|
||||||
|
@ -1837,6 +1881,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale));
|
drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale));
|
||||||
|
kvsConfig(ins);
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
|
||||||
bool isPresent[4];
|
bool isPresent[4];
|
||||||
|
|
Loading…
Reference in New Issue