mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-02 17:27:25 +00:00
Merge branch 'master' of https://github.com/tildearrow/furnace into es5506_alt
* 'master' of https://github.com/tildearrow/furnace: fix sample saving add extra FM effects to effect post handler dev91 - it's a breaking change aaaaaa AY8930: Fix tone and noise period in expanded mode. OPL: fix possible crash
This commit is contained in:
commit
0ab1f69c7c
9 changed files with 108 additions and 11 deletions
|
@ -46,10 +46,10 @@ no plans have been made for TX81Z MIDI passthrough, because:
|
|||
- `28xy`: set reverb of operator.
|
||||
- `x` is the operator (1-4). a value of 0 means "all operators".
|
||||
- `y` is the value.
|
||||
- `29xy`: set EG shift of operator.
|
||||
- `2Axy`: set waveform of operator.
|
||||
- `x` is the operator (1-4). a value of 0 means "all operators".
|
||||
- `y` is the value.
|
||||
- `2Axy`: set waveform of operator.
|
||||
- `2Bxy`: set EG shift of operator.
|
||||
- `x` is the operator (1-4). a value of 0 means "all operators".
|
||||
- `y` is the value.
|
||||
- `2Fxx`: enable envelope hard reset.
|
||||
|
|
|
@ -78,6 +78,8 @@ enum DivDispatchCmds {
|
|||
DIV_CMD_FM_SUS, // (op, value)
|
||||
DIV_CMD_FM_WS, // (op, value)
|
||||
DIV_CMD_FM_SSG, // (op, value)
|
||||
DIV_CMD_FM_REV, // (op, value)
|
||||
DIV_CMD_FM_EG_SHIFT, // (op, value)
|
||||
DIV_CMD_FM_FB, // (value)
|
||||
DIV_CMD_FM_MULT, // (op, value)
|
||||
DIV_CMD_FM_FINE, // (op, value)
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||
|
||||
#define DIV_VERSION "dev90"
|
||||
#define DIV_ENGINE_VERSION 90
|
||||
#define DIV_VERSION "dev91"
|
||||
#define DIV_ENGINE_VERSION 91
|
||||
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define rWrite(a,v) if (!skipRegisterWrites) {pendingWrites[a]=v;}
|
||||
#define immWrite2(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} }
|
||||
|
||||
#define CHIP_DIVIDER 8
|
||||
#define CHIP_DIVIDER 4
|
||||
|
||||
const char* regCheatSheetAY8930[]={
|
||||
"FreqL_A", "00",
|
||||
|
@ -645,7 +645,7 @@ void DivPlatformAY8930::setFlags(unsigned int flags) {
|
|||
chipClock=COLOR_NTSC/2.0;
|
||||
break;
|
||||
}
|
||||
rate=chipClock/8;
|
||||
rate=chipClock/4;
|
||||
for (int i=0; i<3; i++) {
|
||||
oscBuf[i]->rate=rate;
|
||||
}
|
||||
|
|
|
@ -940,6 +940,7 @@ void* DivPlatformOPL::getChanState(int ch) {
|
|||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformOPL::getOscBuffer(int ch) {
|
||||
if (ch>=18) return NULL;
|
||||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
|
|
|
@ -1064,7 +1064,7 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
|
|||
{
|
||||
tone = &m_tone[chan];
|
||||
const int period = std::max<int>(1,tone->period);
|
||||
tone->count += is_expanded_mode() ? 16 : 1;
|
||||
tone->count += is_expanded_mode() ? 16 : (m_feature & PSG_HAS_EXPANDED_MODE) ? 2 : 1;
|
||||
while (tone->count >= period)
|
||||
{
|
||||
tone->duty_cycle = (tone->duty_cycle - 1) & 0x1f;
|
||||
|
@ -1080,7 +1080,7 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
|
|||
* channels.
|
||||
*/
|
||||
m_count_noise = 0;
|
||||
m_prescale_noise ^= 1;
|
||||
m_prescale_noise = (m_prescale_noise + 1) & ((m_feature & PSG_HAS_EXPANDED_MODE) ? 3 : 1);
|
||||
|
||||
if (!m_prescale_noise || is_expanded_mode()) // AY8930 noise generator rate is twice compares as compatibility mode
|
||||
{
|
||||
|
@ -1469,7 +1469,7 @@ ay8910_device::ay8910_device(device_type type, unsigned int clock,
|
|||
m_noise_latch(0),
|
||||
m_mode(0),
|
||||
m_env_step_mask((!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 0x0f : 0x1f),
|
||||
m_step( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 2 : 1),
|
||||
m_step( (feature & PSG_HAS_EXPANDED_MODE) || (psg_type == PSG_TYPE_AY) ? 2 : 1),
|
||||
m_zero_is_off( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 1 : 0),
|
||||
m_par( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? &ay8910_param : &ym2149_param),
|
||||
m_par_env( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? &ay8910_param : &ym2149_param_env),
|
||||
|
@ -1502,7 +1502,7 @@ void ay8910_device::set_type(psg_type_t psg_type)
|
|||
else
|
||||
{
|
||||
m_env_step_mask = 0x1f;
|
||||
m_step = 1;
|
||||
m_step = (m_feature & PSG_HAS_EXPANDED_MODE) ? 2 : 1;
|
||||
m_zero_is_off = 0;
|
||||
m_par = &ym2149_param;
|
||||
m_par_env = &ym2149_param_env;
|
||||
|
|
|
@ -80,6 +80,8 @@ const char* cmdName[]={
|
|||
"FM_SUS",
|
||||
"FM_WS",
|
||||
"FM_SSG",
|
||||
"FM_REV",
|
||||
"FM_EG_SHIFT",
|
||||
"FM_FB",
|
||||
"FM_MULT",
|
||||
"FM_FINE",
|
||||
|
|
|
@ -75,7 +75,7 @@ bool DivSample::save(const char* path) {
|
|||
}
|
||||
sf_command(f, SFC_SET_INSTRUMENT, &inst, sizeof(inst));
|
||||
|
||||
sf_write_short(f,data16,length16);
|
||||
sf_writef_short(f,data16,samples);
|
||||
|
||||
sf_close(f);
|
||||
|
||||
|
|
|
@ -319,6 +319,18 @@ int DivEngine::minVGMVersion(DivSystem which) {
|
|||
#define IS_YM2610 (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT || sysOfChan[ch]==DIV_SYSTEM_YM2610_FULL || sysOfChan[ch]==DIV_SYSTEM_YM2610_FULL_EXT || sysOfChan[ch]==DIV_SYSTEM_YM2610B || sysOfChan[ch]==DIV_SYSTEM_YM2610B_EXT)
|
||||
#define IS_OPM_LIKE (sysOfChan[ch]==DIV_SYSTEM_YM2151 || sysOfChan[ch]==DIV_SYSTEM_OPZ)
|
||||
|
||||
#define OP_EFFECT_MULTI(x,c,op,mask) \
|
||||
case x: \
|
||||
dispatchCmd(DivCommand(c,ch,op,effectVal&mask)); \
|
||||
break;
|
||||
|
||||
#define OP_EFFECT_SINGLE(x,c,maxOp,mask) \
|
||||
case x: \
|
||||
if ((effectVal>>4)>=0 && (effectVal>>4)<=maxOp) { \
|
||||
dispatchCmd(DivCommand(c,ch,(effectVal>>4)-1,effectVal&mask)); \
|
||||
} \
|
||||
break;
|
||||
|
||||
// define systems like:
|
||||
// sysDefs[DIV_SYSTEM_ID]=new DivSysDef(
|
||||
// "Name", "Name (japanese, optional)", fileID, fileID_DMF, channels, isFM, isSTD, vgmVersion,
|
||||
|
@ -436,6 +448,54 @@ void DivEngine::registerSystems() {
|
|||
dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
// fixed frequency effects on OPZ
|
||||
case 0x30: case 0x31: case 0x32: case 0x33:
|
||||
case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
if (sysOfChan[ch]==DIV_SYSTEM_OPZ) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,0,((effect&7)<<8)|effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x38: case 0x39: case 0x3a: case 0x3b:
|
||||
case 0x3c: case 0x3d: case 0x3e: case 0x3f:
|
||||
if (sysOfChan[ch]==DIV_SYSTEM_OPZ) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,1,((effect&7)<<8)|effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x40: case 0x41: case 0x42: case 0x43:
|
||||
case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
if (sysOfChan[ch]==DIV_SYSTEM_OPZ) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,2,((effect&7)<<8)|effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x48: case 0x49: case 0x4a: case 0x4b:
|
||||
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
||||
if (sysOfChan[ch]==DIV_SYSTEM_OPZ) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_FIXFREQ,ch,3,((effect&7)<<8)|effectVal));
|
||||
}
|
||||
break;
|
||||
// extra FM effects here
|
||||
OP_EFFECT_SINGLE(0x50,DIV_CMD_FM_AM,4,1);
|
||||
OP_EFFECT_SINGLE(0x51,DIV_CMD_FM_SL,4,15);
|
||||
OP_EFFECT_SINGLE(0x52,DIV_CMD_FM_RR,4,15);
|
||||
OP_EFFECT_SINGLE(0x53,DIV_CMD_FM_DT,4,7);
|
||||
OP_EFFECT_SINGLE(0x54,DIV_CMD_FM_RS,4,3);
|
||||
OP_EFFECT_SINGLE(0x55,DIV_CMD_FM_SSG,4,(IS_OPM_LIKE?3:15));
|
||||
|
||||
OP_EFFECT_MULTI(0x56,DIV_CMD_FM_DR,-1,31);
|
||||
OP_EFFECT_MULTI(0x57,DIV_CMD_FM_DR,0,31);
|
||||
OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,31);
|
||||
OP_EFFECT_MULTI(0x59,DIV_CMD_FM_DR,2,31);
|
||||
OP_EFFECT_MULTI(0x5a,DIV_CMD_FM_DR,3,31);
|
||||
|
||||
OP_EFFECT_MULTI(0x5b,DIV_CMD_FM_D2R,-1,31);
|
||||
OP_EFFECT_MULTI(0x5c,DIV_CMD_FM_D2R,0,31);
|
||||
OP_EFFECT_MULTI(0x5d,DIV_CMD_FM_D2R,1,31);
|
||||
OP_EFFECT_MULTI(0x5e,DIV_CMD_FM_D2R,2,31);
|
||||
OP_EFFECT_MULTI(0x5f,DIV_CMD_FM_D2R,3,31);
|
||||
|
||||
OP_EFFECT_SINGLE(0x28,DIV_CMD_FM_REV,4,7);
|
||||
OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7);
|
||||
OP_EFFECT_SINGLE(0x2b,DIV_CMD_FM_EG_SHIFT,4,3);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -467,6 +527,21 @@ void DivEngine::registerSystems() {
|
|||
case 0x1b: // AR op2
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,1,effectVal&31));
|
||||
break;
|
||||
|
||||
// extra FM effects here
|
||||
OP_EFFECT_SINGLE(0x50,DIV_CMD_FM_AM,2,1);
|
||||
OP_EFFECT_SINGLE(0x51,DIV_CMD_FM_SL,2,15);
|
||||
OP_EFFECT_SINGLE(0x52,DIV_CMD_FM_RR,2,15);
|
||||
OP_EFFECT_SINGLE(0x53,DIV_CMD_FM_VIB,2,1);
|
||||
OP_EFFECT_SINGLE(0x54,DIV_CMD_FM_RS,2,3);
|
||||
OP_EFFECT_SINGLE(0x55,DIV_CMD_FM_SUS,2,1);
|
||||
|
||||
OP_EFFECT_MULTI(0x56,DIV_CMD_FM_DR,-1,15);
|
||||
OP_EFFECT_MULTI(0x57,DIV_CMD_FM_DR,0,15);
|
||||
OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,15);
|
||||
|
||||
OP_EFFECT_SINGLE(0x5b,DIV_CMD_FM_KSR,2,1);
|
||||
OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -516,6 +591,23 @@ void DivEngine::registerSystems() {
|
|||
case 0x1d: // AR op4
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,3,effectVal&15));
|
||||
break;
|
||||
|
||||
// extra FM effects here
|
||||
OP_EFFECT_SINGLE(0x50,DIV_CMD_FM_AM,4,1);
|
||||
OP_EFFECT_SINGLE(0x51,DIV_CMD_FM_SL,4,15);
|
||||
OP_EFFECT_SINGLE(0x52,DIV_CMD_FM_RR,4,15);
|
||||
OP_EFFECT_SINGLE(0x53,DIV_CMD_FM_VIB,4,1);
|
||||
OP_EFFECT_SINGLE(0x54,DIV_CMD_FM_RS,4,3);
|
||||
OP_EFFECT_SINGLE(0x55,DIV_CMD_FM_SUS,4,1);
|
||||
|
||||
OP_EFFECT_MULTI(0x56,DIV_CMD_FM_DR,-1,15);
|
||||
OP_EFFECT_MULTI(0x57,DIV_CMD_FM_DR,0,15);
|
||||
OP_EFFECT_MULTI(0x58,DIV_CMD_FM_DR,1,15);
|
||||
OP_EFFECT_MULTI(0x59,DIV_CMD_FM_DR,2,15);
|
||||
OP_EFFECT_MULTI(0x5a,DIV_CMD_FM_DR,3,15);
|
||||
|
||||
OP_EFFECT_SINGLE(0x5b,DIV_CMD_FM_KSR,4,1);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue