add effects for rear panning
This commit is contained in:
parent
71e40dc015
commit
707bbb54ea
|
@ -213,6 +213,8 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_MACRO_OFF, // (which)
|
DIV_CMD_MACRO_OFF, // (which)
|
||||||
DIV_CMD_MACRO_ON, // (which)
|
DIV_CMD_MACRO_ON, // (which)
|
||||||
|
|
||||||
|
DIV_CMD_SURROUND_PANNING, // (out, val)
|
||||||
|
|
||||||
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
||||||
|
|
||||||
DIV_CMD_MAX
|
DIV_CMD_MAX
|
||||||
|
|
|
@ -77,6 +77,15 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
||||||
return "81xx: Set panning (left channel)";
|
return "81xx: Set panning (left channel)";
|
||||||
case 0x82:
|
case 0x82:
|
||||||
return "82xx: Set panning (right channel)";
|
return "82xx: Set panning (right channel)";
|
||||||
|
case 0x88:
|
||||||
|
return "88xx: Set panning (rear channels; x: left; y: right)";
|
||||||
|
break;
|
||||||
|
case 0x89:
|
||||||
|
return "89xx: Set panning (rear left channel)";
|
||||||
|
break;
|
||||||
|
case 0x8a:
|
||||||
|
return "8Axx: Set panning (rear right channel)";
|
||||||
|
break;
|
||||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
||||||
return "Cxxx: Set tick rate (hz)";
|
return "Cxxx: Set tick rate (hz)";
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
|
@ -435,6 +444,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
||||||
case DIV_CMD_FM_FINE:
|
case DIV_CMD_FM_FINE:
|
||||||
case DIV_CMD_AY_IO_WRITE:
|
case DIV_CMD_AY_IO_WRITE:
|
||||||
case DIV_CMD_AY_AUTO_PWM:
|
case DIV_CMD_AY_AUTO_PWM:
|
||||||
|
case DIV_CMD_SURROUND_PANNING:
|
||||||
w->writeC(2); // length
|
w->writeC(2); // length
|
||||||
w->writeC(c.value);
|
w->writeC(c.value);
|
||||||
w->writeC(c.value2);
|
w->writeC(c.value2);
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "0.6pre3"
|
#define DIV_VERSION "dev134"
|
||||||
#define DIV_ENGINE_VERSION 133
|
#define DIV_ENGINE_VERSION 134
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
@ -97,7 +97,7 @@ struct DivChannelState {
|
||||||
int delayOrder, delayRow, retrigSpeed, retrigTick;
|
int delayOrder, delayRow, retrigSpeed, retrigTick;
|
||||||
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
|
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
|
||||||
int tremoloDepth, tremoloRate, tremoloPos;
|
int tremoloDepth, tremoloRate, tremoloPos;
|
||||||
unsigned char arp, arpStage, arpTicks, panL, panR;
|
unsigned char arp, arpStage, arpTicks, panL, panR, panRL, panRR;
|
||||||
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
|
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
|
||||||
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, wasShorthandPorta, noteOnInhibit, resetArp;
|
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, wasShorthandPorta, noteOnInhibit, resetArp;
|
||||||
|
|
||||||
|
@ -135,6 +135,8 @@ struct DivChannelState {
|
||||||
arpTicks(1),
|
arpTicks(1),
|
||||||
panL(255),
|
panL(255),
|
||||||
panR(255),
|
panR(255),
|
||||||
|
panRL(0),
|
||||||
|
panRR(0),
|
||||||
doNote(false),
|
doNote(false),
|
||||||
legato(false),
|
legato(false),
|
||||||
portaStop(false),
|
portaStop(false),
|
||||||
|
|
|
@ -2543,6 +2543,16 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OPL3 pan compat
|
||||||
|
if (ds.version<134) {
|
||||||
|
for (int i=0; i<ds.systemLen; i++) {
|
||||||
|
if (ds.system[i]==DIV_SYSTEM_OPL3 ||
|
||||||
|
ds.system[i]==DIV_SYSTEM_OPL3_DRUMS) {
|
||||||
|
ds.systemFlags[i].set("compatPan",true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (active) quitDispatch();
|
if (active) quitDispatch();
|
||||||
BUSY_BEGIN_SOFT;
|
BUSY_BEGIN_SOFT;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
|
|
@ -980,7 +980,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
if (oplType!=3) break;
|
if (oplType!=3) break;
|
||||||
if (c.chan==adpcmChan) break;
|
if (c.chan==adpcmChan) break;
|
||||||
chan[c.chan].pan&=~3;
|
chan[c.chan].pan&=~3;
|
||||||
if (c.value==0 && c.value2==0) {
|
if (c.value==0 && c.value2==0 && compatPan) {
|
||||||
chan[c.chan].pan|=3;
|
chan[c.chan].pan|=3;
|
||||||
} else {
|
} else {
|
||||||
chan[c.chan].pan|=(c.value>0)|((c.value2>0)<<1);
|
chan[c.chan].pan|=(c.value>0)|((c.value2>0)<<1);
|
||||||
|
@ -999,6 +999,33 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_SURROUND_PANNING: {
|
||||||
|
if (oplType!=3) break;
|
||||||
|
if (c.chan==adpcmChan) break;
|
||||||
|
|
||||||
|
if (c.value==2) {
|
||||||
|
chan[c.chan].pan&=3;
|
||||||
|
if (c.value2>0) chan[c.chan].pan|=4;
|
||||||
|
} else if (c.value==3) {
|
||||||
|
if (c.value2>0) chan[c.chan].pan|=8;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||||
|
if (isMuted[c.chan]) {
|
||||||
|
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1));
|
||||||
|
if (ops==4) {
|
||||||
|
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||||
|
if (ops==4) {
|
||||||
|
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_PITCH: {
|
case DIV_CMD_PITCH: {
|
||||||
if (c.chan==adpcmChan) {
|
if (c.chan==adpcmChan) {
|
||||||
if (!chan[c.chan].furnacePCM) break;
|
if (!chan[c.chan].furnacePCM) break;
|
||||||
|
@ -1705,6 +1732,8 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
|
||||||
rate=chipClock/36;
|
rate=chipClock/36;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
compatPan=false;
|
||||||
|
|
||||||
switch (chipType) {
|
switch (chipType) {
|
||||||
default:
|
default:
|
||||||
case 1: case 2: case 8950:
|
case 1: case 2: case 8950:
|
||||||
|
@ -1753,6 +1782,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
|
||||||
CHECK_CUSTOM_CLOCK;
|
CHECK_CUSTOM_CLOCK;
|
||||||
rate=chipClock/288;
|
rate=chipClock/288;
|
||||||
chipRateBase=rate;
|
chipRateBase=rate;
|
||||||
|
compatPan=flags.getBool("compatPan",false);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
switch (flags.getInt("clockSel",0)) {
|
switch (flags.getInt("clockSel",0)) {
|
||||||
|
|
|
@ -92,7 +92,7 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
|
|
||||||
unsigned char lfoValue;
|
unsigned char lfoValue;
|
||||||
|
|
||||||
bool useYMFM, update4OpMask, pretendYMU, downsample;
|
bool useYMFM, update4OpMask, pretendYMU, downsample, compatPan;
|
||||||
|
|
||||||
short oldWrites[512];
|
short oldWrites[512];
|
||||||
short pendingWrites[512];
|
short pendingWrites[512];
|
||||||
|
|
|
@ -213,6 +213,8 @@ const char* cmdName[]={
|
||||||
"MACRO_OFF",
|
"MACRO_OFF",
|
||||||
"MACRO_ON",
|
"MACRO_ON",
|
||||||
|
|
||||||
|
"SURROUND_PANNING",
|
||||||
|
|
||||||
"ALWAYS_SET_VOLUME"
|
"ALWAYS_SET_VOLUME"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -555,6 +557,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
short lastSlide=-1;
|
short lastSlide=-1;
|
||||||
bool calledPorta=false;
|
bool calledPorta=false;
|
||||||
bool panChanged=false;
|
bool panChanged=false;
|
||||||
|
bool surroundPanChanged=false;
|
||||||
|
|
||||||
// effects
|
// effects
|
||||||
for (int j=0; j<curPat[i].effectCols; j++) {
|
for (int j=0; j<curPat[i].effectCols; j++) {
|
||||||
|
@ -585,6 +588,19 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
chan[i].panR=effectVal;
|
chan[i].panR=effectVal;
|
||||||
panChanged=true;
|
panChanged=true;
|
||||||
break;
|
break;
|
||||||
|
case 0x88: // panning rear (split 4-bit)
|
||||||
|
chan[i].panRL=(effectVal>>4)|(effectVal&0xf0);
|
||||||
|
chan[i].panRR=(effectVal&15)|((effectVal&15)<<4);
|
||||||
|
surroundPanChanged=true;
|
||||||
|
break;
|
||||||
|
case 0x89: // panning left (split 8-bit)
|
||||||
|
chan[i].panRL=effectVal;
|
||||||
|
surroundPanChanged=true;
|
||||||
|
break;
|
||||||
|
case 0x8a: // panning right (split 8-bit)
|
||||||
|
chan[i].panRR=effectVal;
|
||||||
|
surroundPanChanged=true;
|
||||||
|
break;
|
||||||
case 0x01: // ramp up
|
case 0x01: // ramp up
|
||||||
if (song.ignoreDuplicateSlides && (lastSlide==0x01 || lastSlide==0x1337)) break;
|
if (song.ignoreDuplicateSlides && (lastSlide==0x01 || lastSlide==0x1337)) break;
|
||||||
lastSlide=0x01;
|
lastSlide=0x01;
|
||||||
|
@ -866,6 +882,10 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (panChanged) {
|
if (panChanged) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_PANNING,i,chan[i].panL,chan[i].panR));
|
dispatchCmd(DivCommand(DIV_CMD_PANNING,i,chan[i].panL,chan[i].panR));
|
||||||
}
|
}
|
||||||
|
if (surroundPanChanged) {
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_SURROUND_PANNING,i,2,chan[i].panRL));
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_SURROUND_PANNING,i,3,chan[i].panRR));
|
||||||
|
}
|
||||||
|
|
||||||
if (insChanged && (chan[i].inPorta || calledPorta) && song.newInsTriggersInPorta) {
|
if (insChanged && (chan[i].inPorta || calledPorta) && song.newInsTriggersInPorta) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL));
|
dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL));
|
||||||
|
|
|
@ -319,9 +319,9 @@ const FurnaceGUIColors fxColors[256]={
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_PANNING,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||||
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
GUI_COLOR_PATTERN_EFFECT_INVALID,
|
||||||
|
|
|
@ -1182,6 +1182,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
case DIV_SYSTEM_OPL3:
|
case DIV_SYSTEM_OPL3:
|
||||||
case DIV_SYSTEM_OPL3_DRUMS: {
|
case DIV_SYSTEM_OPL3_DRUMS: {
|
||||||
int clockSel=flags.getInt("clockSel",0);
|
int clockSel=flags.getInt("clockSel",0);
|
||||||
|
bool compatPan=flags.getBool("compatPan",false);
|
||||||
|
|
||||||
ImGui::Text("Clock rate:");
|
ImGui::Text("Clock rate:");
|
||||||
if (ImGui::RadioButton("14.32MHz (NTSC)",clockSel==0)) {
|
if (ImGui::RadioButton("14.32MHz (NTSC)",clockSel==0)) {
|
||||||
|
@ -1205,9 +1206,14 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
altered=true;
|
altered=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("Compatible panning (0800)",&compatPan)) {
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
e->lockSave([&]() {
|
e->lockSave([&]() {
|
||||||
flags.set("clockSel",clockSel);
|
flags.set("clockSel",clockSel);
|
||||||
|
flags.set("compatPan",compatPan);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue