mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 08:23:01 +00:00
implement more effects
- C64: set fine duty and filter - Neo Geo: slide SSG envelope
This commit is contained in:
parent
69b56e6d4c
commit
651db5784e
7 changed files with 67 additions and 0 deletions
|
@ -104,6 +104,8 @@ the following effects are provided:
|
||||||
- if `y` is 1 then the envelope will affect this channel.
|
- if `y` is 1 then the envelope will affect this channel.
|
||||||
- `23xx`: set envelope period low byte.
|
- `23xx`: set envelope period low byte.
|
||||||
- `24xx`: set envelope period high byte.
|
- `24xx`: set envelope period high byte.
|
||||||
|
- `25xx`: slide envelope period up.
|
||||||
|
- `26xx`: slide envelope period down.
|
||||||
|
|
||||||
a lower envelope period will make the envelope run faster.
|
a lower envelope period will make the envelope run faster.
|
||||||
|
|
||||||
|
|
|
@ -54,10 +54,13 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_C64_FILTER_RESET,
|
DIV_CMD_C64_FILTER_RESET,
|
||||||
DIV_CMD_C64_DUTY_RESET,
|
DIV_CMD_C64_DUTY_RESET,
|
||||||
DIV_CMD_C64_EXTENDED,
|
DIV_CMD_C64_EXTENDED,
|
||||||
|
DIV_CMD_C64_FINE_DUTY,
|
||||||
|
DIV_CMD_C64_FINE_CUTOFF,
|
||||||
|
|
||||||
DIV_CMD_AY_ENVELOPE_SET,
|
DIV_CMD_AY_ENVELOPE_SET,
|
||||||
DIV_CMD_AY_ENVELOPE_LOW,
|
DIV_CMD_AY_ENVELOPE_LOW,
|
||||||
DIV_CMD_AY_ENVELOPE_HIGH,
|
DIV_CMD_AY_ENVELOPE_HIGH,
|
||||||
|
DIV_CMD_AY_ENVELOPE_SLIDE,
|
||||||
|
|
||||||
DIV_ALWAYS_SET_VOLUME,
|
DIV_ALWAYS_SET_VOLUME,
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,11 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
||||||
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_C64_FINE_DUTY:
|
||||||
|
chan[c.chan].duty=c.value;
|
||||||
|
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
||||||
|
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
||||||
|
break;
|
||||||
case DIV_CMD_WAVE:
|
case DIV_CMD_WAVE:
|
||||||
chan[c.chan].wave=c.value;
|
chan[c.chan].wave=c.value;
|
||||||
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
|
||||||
|
@ -220,6 +225,10 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
filtCut=c.value*2047/100;
|
filtCut=c.value*2047/100;
|
||||||
updateFilter();
|
updateFilter();
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_C64_FINE_CUTOFF:
|
||||||
|
filtCut=c.value;
|
||||||
|
updateFilter();
|
||||||
|
break;
|
||||||
case DIV_CMD_C64_RESONANCE:
|
case DIV_CMD_C64_RESONANCE:
|
||||||
if (c.value>15) c.value=15;
|
if (c.value>15) c.value=15;
|
||||||
filtRes=c.value;
|
filtRes=c.value;
|
||||||
|
|
|
@ -99,6 +99,26 @@ void DivPlatformYM2610::tick() {
|
||||||
((chan[4].psgMode&2)<<2)|
|
((chan[4].psgMode&2)<<2)|
|
||||||
((chan[5].psgMode&2)<<3)|
|
((chan[5].psgMode&2)<<3)|
|
||||||
((chan[6].psgMode&2)<<4)));
|
((chan[6].psgMode&2)<<4)));
|
||||||
|
|
||||||
|
if (ayEnvSlide!=0) {
|
||||||
|
ayEnvSlideLow+=ayEnvSlide;
|
||||||
|
while (ayEnvSlideLow>7) {
|
||||||
|
ayEnvSlideLow-=8;
|
||||||
|
if (ayEnvPeriod<0xffff) {
|
||||||
|
ayEnvPeriod++;
|
||||||
|
immWrite(0x0b,ayEnvPeriod);
|
||||||
|
immWrite(0x0c,ayEnvPeriod>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ayEnvSlideLow<-7) {
|
||||||
|
ayEnvSlideLow+=8;
|
||||||
|
if (ayEnvPeriod>0) {
|
||||||
|
ayEnvPeriod--;
|
||||||
|
immWrite(0x0b,ayEnvPeriod);
|
||||||
|
immWrite(0x0c,ayEnvPeriod>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FM
|
// FM
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
|
@ -462,6 +482,10 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
immWrite(0x0b,ayEnvPeriod);
|
immWrite(0x0b,ayEnvPeriod);
|
||||||
immWrite(0x0c,ayEnvPeriod>>8);
|
immWrite(0x0c,ayEnvPeriod>>8);
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_AY_ENVELOPE_SLIDE:
|
||||||
|
if (c.chan<4 || c.chan>6) break;
|
||||||
|
ayEnvSlide=c.value;
|
||||||
|
break;
|
||||||
case DIV_ALWAYS_SET_VOLUME:
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -543,6 +567,8 @@ void DivPlatformYM2610::reset() {
|
||||||
sampleBank=0;
|
sampleBank=0;
|
||||||
ayEnvPeriod=0;
|
ayEnvPeriod=0;
|
||||||
ayEnvMode=0;
|
ayEnvMode=0;
|
||||||
|
ayEnvSlide=0;
|
||||||
|
ayEnvSlideLow=0;
|
||||||
|
|
||||||
delay=0;
|
delay=0;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ class DivPlatformYM2610: public DivDispatch {
|
||||||
short pendingWrites[512];
|
short pendingWrites[512];
|
||||||
unsigned char ayEnvMode;
|
unsigned char ayEnvMode;
|
||||||
unsigned short ayEnvPeriod;
|
unsigned short ayEnvPeriod;
|
||||||
|
short ayEnvSlideLow;
|
||||||
|
short ayEnvSlide;
|
||||||
|
|
||||||
int octave(int freq);
|
int octave(int freq);
|
||||||
int toFreq(int freq);
|
int toFreq(int freq);
|
||||||
|
|
|
@ -66,10 +66,13 @@ const char* cmdName[DIV_CMD_MAX]={
|
||||||
"C64_FILTER_RESET",
|
"C64_FILTER_RESET",
|
||||||
"C64_DUTY_RESET",
|
"C64_DUTY_RESET",
|
||||||
"C64_EXTENDED",
|
"C64_EXTENDED",
|
||||||
|
"C64_FINE_DUTY",
|
||||||
|
"C64_FINE_CUTOFF",
|
||||||
|
|
||||||
"AY_ENVELOPE_SET",
|
"AY_ENVELOPE_SET",
|
||||||
"AY_ENVELOPE_LOW",
|
"AY_ENVELOPE_LOW",
|
||||||
"AY_ENVELOPE_HIGH",
|
"AY_ENVELOPE_HIGH",
|
||||||
|
"AY_ENVELOPE_SLIDE",
|
||||||
|
|
||||||
"ALWAYS_SET_VOLUME"
|
"ALWAYS_SET_VOLUME"
|
||||||
};
|
};
|
||||||
|
@ -261,6 +264,16 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x25: // UNOFFICIAL: Neo Geo PSG envelope slide up
|
||||||
|
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,-effectVal));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x26: // UNOFFICIAL: Neo Geo PSG envelope slide down
|
||||||
|
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,effectVal));
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +310,16 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
case 0x1e: // extended
|
case 0x1e: // extended
|
||||||
dispatchCmd(DivCommand(DIV_CMD_C64_EXTENDED,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_C64_EXTENDED,ch,effectVal));
|
||||||
break;
|
break;
|
||||||
|
case 0x30: case 0x31: case 0x32: case 0x33:
|
||||||
|
case 0x34: case 0x35: case 0x36: case 0x37:
|
||||||
|
case 0x38: case 0x39: case 0x3a: case 0x3b:
|
||||||
|
case 0x3c: case 0x3d: case 0x3e: case 0x3f: // fine duty
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_C64_FINE_DUTY,ch,((effect&0x0f)<<8)|effectVal));
|
||||||
|
break;
|
||||||
|
case 0x40: case 0x41: case 0x42: case 0x43:
|
||||||
|
case 0x44: case 0x45: case 0x46: case 0x47: // fine cutoff
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_C64_FINE_CUTOFF,ch,((effect&0x07)<<8)|effectVal));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1434,6 +1434,8 @@ void FurnaceGUI::drawPattern() {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||||
} else if (pat->data[i][index]<0x30) {
|
} else if (pat->data[i][index]<0x30) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY]);
|
||||||
|
} else if (pat->data[i][index]<0x48) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||||
} else if (pat->data[i][index]<0xe0) {
|
} else if (pat->data[i][index]<0xe0) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||||
} else if (pat->data[i][index]<0xf0) {
|
} else if (pat->data[i][index]<0xf0) {
|
||||||
|
|
Loading…
Reference in a new issue