add effects for rear panning

This commit is contained in:
tildearrow 2023-01-05 03:08:57 -05:00
parent 71e40dc015
commit 707bbb54ea
9 changed files with 88 additions and 8 deletions

View File

@ -213,6 +213,8 @@ enum DivDispatchCmds {
DIV_CMD_MACRO_OFF, // (which)
DIV_CMD_MACRO_ON, // (which)
DIV_CMD_SURROUND_PANNING, // (out, val)
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
DIV_CMD_MAX

View File

@ -77,6 +77,15 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
return "81xx: Set panning (left channel)";
case 0x82:
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:
return "Cxxx: Set tick rate (hz)";
case 0xe0:
@ -435,6 +444,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
case DIV_CMD_FM_FINE:
case DIV_CMD_AY_IO_WRITE:
case DIV_CMD_AY_AUTO_PWM:
case DIV_CMD_SURROUND_PANNING:
w->writeC(2); // length
w->writeC(c.value);
w->writeC(c.value2);

View File

@ -47,8 +47,8 @@
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
#define BUSY_END isBusy.unlock(); softLocked=false;
#define DIV_VERSION "0.6pre3"
#define DIV_ENGINE_VERSION 133
#define DIV_VERSION "dev134"
#define DIV_ENGINE_VERSION 134
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02
@ -97,7 +97,7 @@ struct DivChannelState {
int delayOrder, delayRow, retrigSpeed, retrigTick;
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
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 arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, wasShorthandPorta, noteOnInhibit, resetArp;
@ -135,6 +135,8 @@ struct DivChannelState {
arpTicks(1),
panL(255),
panR(255),
panRL(0),
panRR(0),
doNote(false),
legato(false),
portaStop(false),

View File

@ -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();
BUSY_BEGIN_SOFT;
saveLock.lock();

View File

@ -980,7 +980,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
if (oplType!=3) break;
if (c.chan==adpcmChan) break;
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;
} else {
chan[c.chan].pan|=(c.value>0)|((c.value2>0)<<1);
@ -999,6 +999,33 @@ int DivPlatformOPL::dispatch(DivCommand c) {
}
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: {
if (c.chan==adpcmChan) {
if (!chan[c.chan].furnacePCM) break;
@ -1705,6 +1732,8 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
rate=chipClock/36;
}*/
compatPan=false;
switch (chipType) {
default:
case 1: case 2: case 8950:
@ -1753,6 +1782,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/288;
chipRateBase=rate;
compatPan=flags.getBool("compatPan",false);
break;
case 4:
switch (flags.getInt("clockSel",0)) {

View File

@ -92,7 +92,7 @@ class DivPlatformOPL: public DivDispatch {
unsigned char lfoValue;
bool useYMFM, update4OpMask, pretendYMU, downsample;
bool useYMFM, update4OpMask, pretendYMU, downsample, compatPan;
short oldWrites[512];
short pendingWrites[512];

View File

@ -213,6 +213,8 @@ const char* cmdName[]={
"MACRO_OFF",
"MACRO_ON",
"SURROUND_PANNING",
"ALWAYS_SET_VOLUME"
};
@ -555,6 +557,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
short lastSlide=-1;
bool calledPorta=false;
bool panChanged=false;
bool surroundPanChanged=false;
// effects
for (int j=0; j<curPat[i].effectCols; j++) {
@ -585,6 +588,19 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].panR=effectVal;
panChanged=true;
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
if (song.ignoreDuplicateSlides && (lastSlide==0x01 || lastSlide==0x1337)) break;
lastSlide=0x01;
@ -866,6 +882,10 @@ void DivEngine::processRow(int i, bool afterDelay) {
if (panChanged) {
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) {
dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL));

View File

@ -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_PANNING,
GUI_COLOR_PATTERN_EFFECT_PANNING,
GUI_COLOR_PATTERN_EFFECT_PANNING,
GUI_COLOR_PATTERN_EFFECT_INVALID,
GUI_COLOR_PATTERN_EFFECT_INVALID,
GUI_COLOR_PATTERN_EFFECT_INVALID,

View File

@ -1182,6 +1182,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
case DIV_SYSTEM_OPL3:
case DIV_SYSTEM_OPL3_DRUMS: {
int clockSel=flags.getInt("clockSel",0);
bool compatPan=flags.getBool("compatPan",false);
ImGui::Text("Clock rate:");
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;
}
if (ImGui::Checkbox("Compatible panning (0800)",&compatPan)) {
altered=true;
}
if (altered) {
e->lockSave([&]() {
flags.set("clockSel",clockSel);
flags.set("compatPan",compatPan);
});
}
break;