Merge branch 'master' of https://github.com/tildearrow/furnace into ym2610b
This commit is contained in:
commit
1631af8f8e
21 changed files with 700 additions and 284 deletions
|
|
@ -206,6 +206,8 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
case DIV_SYSTEM_OPLL_DRUMS:
|
||||
case DIV_SYSTEM_VRC7:
|
||||
dispatch=new DivPlatformOPLL;
|
||||
((DivPlatformOPLL*)dispatch)->setVRC7(sys==DIV_SYSTEM_VRC7);
|
||||
((DivPlatformOPLL*)dispatch)->setProperDrums(sys==DIV_SYSTEM_OPLL_DRUMS);
|
||||
break;
|
||||
case DIV_SYSTEM_SAA1099: {
|
||||
int saaCore=eng->getConfInt("saaCore",0);
|
||||
|
|
|
|||
|
|
@ -501,6 +501,7 @@ void DivEngine::renderSamples() {
|
|||
|
||||
// step 4: allocate qsound pcm samples
|
||||
if (qsoundMem==NULL) qsoundMem=new unsigned char[16777216];
|
||||
memset(qsoundMem,0,16777216);
|
||||
|
||||
memPos=0;
|
||||
for (int i=0; i<song.sampleLen; i++) {
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@
|
|||
warnings+=(String("\n")+x); \
|
||||
}
|
||||
|
||||
#define DIV_VERSION "dev60"
|
||||
#define DIV_ENGINE_VERSION 60
|
||||
#define DIV_VERSION "dev61"
|
||||
#define DIV_ENGINE_VERSION 61
|
||||
|
||||
enum DivStatusView {
|
||||
DIV_STATUS_NOTHING=0,
|
||||
|
|
|
|||
|
|
@ -302,6 +302,75 @@ void DivInstrument::putInsData(SafeWriter* w) {
|
|||
w->writeI(op.d2rMacroRel);
|
||||
w->writeI(op.ssgMacroRel);
|
||||
}
|
||||
|
||||
// extended op macros
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
|
||||
|
||||
w->writeI(op.damMacroLen);
|
||||
w->writeI(op.dvbMacroLen);
|
||||
w->writeI(op.egtMacroLen);
|
||||
w->writeI(op.kslMacroLen);
|
||||
w->writeI(op.susMacroLen);
|
||||
w->writeI(op.vibMacroLen);
|
||||
w->writeI(op.wsMacroLen);
|
||||
w->writeI(op.ksrMacroLen);
|
||||
|
||||
w->writeI(op.damMacroLoop);
|
||||
w->writeI(op.dvbMacroLoop);
|
||||
w->writeI(op.egtMacroLoop);
|
||||
w->writeI(op.kslMacroLoop);
|
||||
w->writeI(op.susMacroLoop);
|
||||
w->writeI(op.vibMacroLoop);
|
||||
w->writeI(op.wsMacroLoop);
|
||||
w->writeI(op.ksrMacroLoop);
|
||||
|
||||
w->writeI(op.damMacroRel);
|
||||
w->writeI(op.dvbMacroRel);
|
||||
w->writeI(op.egtMacroRel);
|
||||
w->writeI(op.kslMacroRel);
|
||||
w->writeI(op.susMacroRel);
|
||||
w->writeI(op.vibMacroRel);
|
||||
w->writeI(op.wsMacroRel);
|
||||
w->writeI(op.ksrMacroRel);
|
||||
|
||||
w->writeC(op.damMacroOpen);
|
||||
w->writeC(op.dvbMacroOpen);
|
||||
w->writeC(op.egtMacroOpen);
|
||||
w->writeC(op.kslMacroOpen);
|
||||
w->writeC(op.susMacroOpen);
|
||||
w->writeC(op.vibMacroOpen);
|
||||
w->writeC(op.wsMacroOpen);
|
||||
w->writeC(op.ksrMacroOpen);
|
||||
}
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
|
||||
for (int j=0; j<op.damMacroLen; j++) {
|
||||
w->writeC(op.damMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.dvbMacroLen; j++) {
|
||||
w->writeC(op.dvbMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.egtMacroLen; j++) {
|
||||
w->writeC(op.egtMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.kslMacroLen; j++) {
|
||||
w->writeC(op.kslMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.susMacroLen; j++) {
|
||||
w->writeC(op.susMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.vibMacroLen; j++) {
|
||||
w->writeC(op.vibMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.wsMacroLen; j++) {
|
||||
w->writeC(op.wsMacro[j]);
|
||||
}
|
||||
for (int j=0; j<op.ksrMacroLen; j++) {
|
||||
w->writeC(op.ksrMacro[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||
|
|
@ -570,6 +639,61 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
|||
}
|
||||
}
|
||||
|
||||
// extended op macros
|
||||
if (version>=61) {
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
|
||||
|
||||
op.damMacroLen=reader.readI();
|
||||
op.dvbMacroLen=reader.readI();
|
||||
op.egtMacroLen=reader.readI();
|
||||
op.kslMacroLen=reader.readI();
|
||||
op.susMacroLen=reader.readI();
|
||||
op.vibMacroLen=reader.readI();
|
||||
op.wsMacroLen=reader.readI();
|
||||
op.ksrMacroLen=reader.readI();
|
||||
|
||||
op.damMacroLoop=reader.readI();
|
||||
op.dvbMacroLoop=reader.readI();
|
||||
op.egtMacroLoop=reader.readI();
|
||||
op.kslMacroLoop=reader.readI();
|
||||
op.susMacroLoop=reader.readI();
|
||||
op.vibMacroLoop=reader.readI();
|
||||
op.wsMacroLoop=reader.readI();
|
||||
op.ksrMacroLoop=reader.readI();
|
||||
|
||||
op.damMacroRel=reader.readI();
|
||||
op.dvbMacroRel=reader.readI();
|
||||
op.egtMacroRel=reader.readI();
|
||||
op.kslMacroRel=reader.readI();
|
||||
op.susMacroRel=reader.readI();
|
||||
op.vibMacroRel=reader.readI();
|
||||
op.wsMacroRel=reader.readI();
|
||||
op.ksrMacroRel=reader.readI();
|
||||
|
||||
op.damMacroOpen=reader.readC();
|
||||
op.dvbMacroOpen=reader.readC();
|
||||
op.egtMacroOpen=reader.readC();
|
||||
op.kslMacroOpen=reader.readC();
|
||||
op.susMacroOpen=reader.readC();
|
||||
op.vibMacroOpen=reader.readC();
|
||||
op.wsMacroOpen=reader.readC();
|
||||
op.ksrMacroOpen=reader.readC();
|
||||
}
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
|
||||
reader.read(op.damMacro,op.damMacroLen);
|
||||
reader.read(op.dvbMacro,op.dvbMacroLen);
|
||||
reader.read(op.egtMacro,op.egtMacroLen);
|
||||
reader.read(op.kslMacro,op.kslMacroLen);
|
||||
reader.read(op.susMacro,op.susMacroLen);
|
||||
reader.read(op.vibMacro,op.vibMacroLen);
|
||||
reader.read(op.wsMacro,op.wsMacroLen);
|
||||
reader.read(op.ksrMacro,op.ksrMacroLen);
|
||||
}
|
||||
}
|
||||
|
||||
return DIV_DATA_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,11 +50,26 @@ enum DivInstrumentType {
|
|||
DIV_INS_MIKEY=23,
|
||||
};
|
||||
|
||||
// FM operator structure:
|
||||
// - OPN:
|
||||
// - AM, AR, DR, MULT, RR, SL, TL, RS, DT, D2R, SSG-EG
|
||||
// - OPM:
|
||||
// - AM, AR, DR, MULT, RR, SL, TL, DT2, RS, DT, D2R
|
||||
// - OPLL:
|
||||
// - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S
|
||||
// - KSL, VIB, KSR
|
||||
// - OPL:
|
||||
// - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S
|
||||
// - KSL, VIB, WS (OPL2/3), KSR
|
||||
// - OPZ: NOT FINAL!
|
||||
// - AM, AR, DR, MULT (CRS), RR, SL, TL, DT2, RS, DT, D2R
|
||||
// - KSL = LS, WS, DVB = MULT (FINE), DAM = REV, EGT = EGShift
|
||||
|
||||
struct DivInstrumentFM {
|
||||
unsigned char alg, fb, fms, ams, ops, opllPreset;
|
||||
struct Operator {
|
||||
unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
||||
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL
|
||||
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL/OPZ
|
||||
Operator():
|
||||
am(0),
|
||||
ar(0),
|
||||
|
|
@ -161,31 +176,55 @@ struct DivInstrumentSTD {
|
|||
unsigned char dtMacro[256];
|
||||
unsigned char d2rMacro[256];
|
||||
unsigned char ssgMacro[256];
|
||||
unsigned char damMacro[256];
|
||||
unsigned char dvbMacro[256];
|
||||
unsigned char egtMacro[256];
|
||||
unsigned char kslMacro[256];
|
||||
unsigned char susMacro[256];
|
||||
unsigned char vibMacro[256];
|
||||
unsigned char wsMacro[256];
|
||||
unsigned char ksrMacro[256];
|
||||
bool amMacroOpen, arMacroOpen, drMacroOpen, multMacroOpen;
|
||||
bool rrMacroOpen, slMacroOpen, tlMacroOpen, dt2MacroOpen;
|
||||
bool rsMacroOpen, dtMacroOpen, d2rMacroOpen, ssgMacroOpen;
|
||||
bool damMacroOpen, dvbMacroOpen, egtMacroOpen, kslMacroOpen;
|
||||
bool susMacroOpen, vibMacroOpen, wsMacroOpen, ksrMacroOpen;
|
||||
unsigned char amMacroLen, arMacroLen, drMacroLen, multMacroLen;
|
||||
unsigned char rrMacroLen, slMacroLen, tlMacroLen, dt2MacroLen;
|
||||
unsigned char rsMacroLen, dtMacroLen, d2rMacroLen, ssgMacroLen;
|
||||
unsigned char damMacroLen, dvbMacroLen, egtMacroLen, kslMacroLen;
|
||||
unsigned char susMacroLen, vibMacroLen, wsMacroLen, ksrMacroLen;
|
||||
signed char amMacroLoop, arMacroLoop, drMacroLoop, multMacroLoop;
|
||||
signed char rrMacroLoop, slMacroLoop, tlMacroLoop, dt2MacroLoop;
|
||||
signed char rsMacroLoop, dtMacroLoop, d2rMacroLoop, ssgMacroLoop;
|
||||
signed char damMacroLoop, dvbMacroLoop, egtMacroLoop, kslMacroLoop;
|
||||
signed char susMacroLoop, vibMacroLoop, wsMacroLoop, ksrMacroLoop;
|
||||
signed char amMacroRel, arMacroRel, drMacroRel, multMacroRel;
|
||||
signed char rrMacroRel, slMacroRel, tlMacroRel, dt2MacroRel;
|
||||
signed char rsMacroRel, dtMacroRel, d2rMacroRel, ssgMacroRel;
|
||||
signed char damMacroRel, dvbMacroRel, egtMacroRel, kslMacroRel;
|
||||
signed char susMacroRel, vibMacroRel, wsMacroRel, ksrMacroRel;
|
||||
OpMacro():
|
||||
amMacroOpen(false), arMacroOpen(false), drMacroOpen(false), multMacroOpen(false),
|
||||
rrMacroOpen(false), slMacroOpen(false), tlMacroOpen(true), dt2MacroOpen(false),
|
||||
rsMacroOpen(false), dtMacroOpen(false), d2rMacroOpen(false), ssgMacroOpen(false),
|
||||
damMacroOpen(false), dvbMacroOpen(false), egtMacroOpen(false), kslMacroOpen(false),
|
||||
susMacroOpen(false), vibMacroOpen(false), wsMacroOpen(false), ksrMacroOpen(false),
|
||||
amMacroLen(0), arMacroLen(0), drMacroLen(0), multMacroLen(0),
|
||||
rrMacroLen(0), slMacroLen(0), tlMacroLen(0), dt2MacroLen(0),
|
||||
rsMacroLen(0), dtMacroLen(0), d2rMacroLen(0), ssgMacroLen(0),
|
||||
damMacroLen(0), dvbMacroLen(0), egtMacroLen(0), kslMacroLen(0),
|
||||
susMacroLen(0), vibMacroLen(0), wsMacroLen(0), ksrMacroLen(0),
|
||||
amMacroLoop(-1), arMacroLoop(-1), drMacroLoop(-1), multMacroLoop(-1),
|
||||
rrMacroLoop(-1), slMacroLoop(-1), tlMacroLoop(-1), dt2MacroLoop(-1),
|
||||
rsMacroLoop(-1), dtMacroLoop(-1), d2rMacroLoop(-1), ssgMacroLoop(-1),
|
||||
damMacroLoop(-1), dvbMacroLoop(-1), egtMacroLoop(-1), kslMacroLoop(-1),
|
||||
susMacroLoop(-1), vibMacroLoop(-1), wsMacroLoop(-1), ksrMacroLoop(-1),
|
||||
amMacroRel(-1), arMacroRel(-1), drMacroRel(-1), multMacroRel(-1),
|
||||
rrMacroRel(-1), slMacroRel(-1), tlMacroRel(-1), dt2MacroRel(-1),
|
||||
rsMacroRel(-1), dtMacroRel(-1), d2rMacroRel(-1), ssgMacroRel(-1) {
|
||||
rsMacroRel(-1), dtMacroRel(-1), d2rMacroRel(-1), ssgMacroRel(-1),
|
||||
damMacroRel(-1), dvbMacroRel(-1), egtMacroRel(-1), kslMacroRel(-1),
|
||||
susMacroRel(-1), vibMacroRel(-1), wsMacroRel(-1), ksrMacroRel(-1) {
|
||||
memset(amMacro,0,256);
|
||||
memset(arMacro,0,256);
|
||||
memset(drMacro,0,256);
|
||||
|
|
@ -198,6 +237,14 @@ struct DivInstrumentSTD {
|
|||
memset(dtMacro,0,256);
|
||||
memset(d2rMacro,0,256);
|
||||
memset(ssgMacro,0,256);
|
||||
memset(damMacro,0,256);
|
||||
memset(dvbMacro,0,256);
|
||||
memset(egtMacro,0,256);
|
||||
memset(kslMacro,0,256);
|
||||
memset(susMacro,0,256);
|
||||
memset(vibMacro,0,256);
|
||||
memset(wsMacro,0,256);
|
||||
memset(ksrMacro,0,256);
|
||||
}
|
||||
} opMacros[4];
|
||||
DivInstrumentSTD():
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
} \
|
||||
}
|
||||
|
||||
// CPU hell
|
||||
void DivMacroInt::next() {
|
||||
if (ins==NULL) return;
|
||||
|
||||
|
|
@ -79,6 +80,16 @@ void DivMacroInt::next() {
|
|||
doMacro(o.finishedDt,o.hadDt,o.hasDt,o.dt,o.dtPos,m.dtMacro,m.dtMacroLen,m.dtMacroLoop,m.dtMacroRel);
|
||||
doMacro(o.finishedD2r,o.hadD2r,o.hasD2r,o.d2r,o.d2rPos,m.d2rMacro,m.d2rMacroLen,m.d2rMacroLoop,m.d2rMacroRel);
|
||||
doMacro(o.finishedSsg,o.hadSsg,o.hasSsg,o.ssg,o.ssgPos,m.ssgMacro,m.ssgMacroLen,m.ssgMacroLoop,m.ssgMacroRel);
|
||||
|
||||
doMacro(o.finishedDam,o.hadDam,o.hasDam,o.dam,o.damPos,m.damMacro,m.damMacroLen,m.damMacroLoop,m.damMacroRel);
|
||||
doMacro(o.finishedDvb,o.hadDvb,o.hasDvb,o.dvb,o.dvbPos,m.dvbMacro,m.dvbMacroLen,m.dvbMacroLoop,m.dvbMacroRel);
|
||||
doMacro(o.finishedEgt,o.hadEgt,o.hasEgt,o.egt,o.egtPos,m.egtMacro,m.egtMacroLen,m.egtMacroLoop,m.egtMacroRel);
|
||||
doMacro(o.finishedKsl,o.hadKsl,o.hasKsl,o.ksl,o.kslPos,m.kslMacro,m.kslMacroLen,m.kslMacroLoop,m.kslMacroRel);
|
||||
|
||||
doMacro(o.finishedSus,o.hadSus,o.hasSus,o.sus,o.susPos,m.susMacro,m.susMacroLen,m.susMacroLoop,m.susMacroRel);
|
||||
doMacro(o.finishedVib,o.hadVib,o.hasVib,o.vib,o.vibPos,m.vibMacro,m.vibMacroLen,m.vibMacroLoop,m.vibMacroRel);
|
||||
doMacro(o.finishedWs,o.hadWs,o.hasWs,o.ws,o.wsPos,m.wsMacro,m.wsMacroLen,m.wsMacroLoop,m.wsMacroRel);
|
||||
doMacro(o.finishedKsr,o.hadKsr,o.hasKsr,o.ksr,o.ksrPos,m.ksrMacro,m.ksrMacroLen,m.ksrMacroLoop,m.ksrMacroRel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -280,6 +291,47 @@ void DivMacroInt::init(DivInstrument* which) {
|
|||
o.hasSsg=true;
|
||||
o.willSsg=true;
|
||||
}
|
||||
|
||||
if (m.damMacroLen>0) {
|
||||
o.hadDam=true;
|
||||
o.hasDam=true;
|
||||
o.willDam=true;
|
||||
}
|
||||
if (m.dvbMacroLen>0) {
|
||||
o.hadDvb=true;
|
||||
o.hasDvb=true;
|
||||
o.willDvb=true;
|
||||
}
|
||||
if (m.egtMacroLen>0) {
|
||||
o.hadEgt=true;
|
||||
o.hasEgt=true;
|
||||
o.willEgt=true;
|
||||
}
|
||||
if (m.kslMacroLen>0) {
|
||||
o.hadKsl=true;
|
||||
o.hasKsl=true;
|
||||
o.willKsl=true;
|
||||
}
|
||||
if (m.susMacroLen>0) {
|
||||
o.hadSus=true;
|
||||
o.hasSus=true;
|
||||
o.willSus=true;
|
||||
}
|
||||
if (m.vibMacroLen>0) {
|
||||
o.hadVib=true;
|
||||
o.hasVib=true;
|
||||
o.willVib=true;
|
||||
}
|
||||
if (m.wsMacroLen>0) {
|
||||
o.hadWs=true;
|
||||
o.hasWs=true;
|
||||
o.willWs=true;
|
||||
}
|
||||
if (m.ksrMacroLen>0) {
|
||||
o.hadKsr=true;
|
||||
o.hasKsr=true;
|
||||
o.willKsr=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,26 +42,38 @@ class DivMacroInt {
|
|||
int amPos, arPos, drPos, multPos;
|
||||
int rrPos, slPos, tlPos, dt2Pos;
|
||||
int rsPos, dtPos, d2rPos, ssgPos;
|
||||
int damPos, dvbPos, egtPos, kslPos;
|
||||
int susPos, vibPos, wsPos, ksrPos;
|
||||
|
||||
int am, ar, dr, mult;
|
||||
int rr, sl, tl, dt2;
|
||||
int rs, dt, d2r, ssg;
|
||||
int dam, dvb, egt, ksl;
|
||||
int sus, vib, ws, ksr;
|
||||
|
||||
bool hasAm, hasAr, hasDr, hasMult;
|
||||
bool hasRr, hasSl, hasTl, hasDt2;
|
||||
bool hasRs, hasDt, hasD2r, hasSsg;
|
||||
bool hasDam, hasDvb, hasEgt, hasKsl;
|
||||
bool hasSus, hasVib, hasWs, hasKsr;
|
||||
|
||||
bool hadAm, hadAr, hadDr, hadMult;
|
||||
bool hadRr, hadSl, hadTl, hadDt2;
|
||||
bool hadRs, hadDt, hadD2r, hadSsg;
|
||||
bool hadDam, hadDvb, hadEgt, hadKsl;
|
||||
bool hadSus, hadVib, hadWs, hadKsr;
|
||||
|
||||
bool finishedAm, finishedAr, finishedDr, finishedMult;
|
||||
bool finishedRr, finishedSl, finishedTl, finishedDt2;
|
||||
bool finishedRs, finishedDt, finishedD2r, finishedSsg;
|
||||
bool finishedDam, finishedDvb, finishedEgt, finishedKsl;
|
||||
bool finishedSus, finishedVib, finishedWs, finishedKsr;
|
||||
|
||||
bool willAm, willAr, willDr, willMult;
|
||||
bool willRr, willSl, willTl, willDt2;
|
||||
bool willRs, willDt, willD2r, willSsg;
|
||||
bool willDam, willDvb, willEgt, willKsl;
|
||||
bool willSus, willVib, willWs, willKsr;
|
||||
IntOp():
|
||||
amPos(0),
|
||||
arPos(0),
|
||||
|
|
@ -75,6 +87,14 @@ class DivMacroInt {
|
|||
dtPos(0),
|
||||
d2rPos(0),
|
||||
ssgPos(0),
|
||||
damPos(0),
|
||||
dvbPos(0),
|
||||
egtPos(0),
|
||||
kslPos(0),
|
||||
susPos(0),
|
||||
vibPos(0),
|
||||
wsPos(0),
|
||||
ksrPos(0),
|
||||
am(0),
|
||||
ar(0),
|
||||
dr(0),
|
||||
|
|
@ -87,18 +107,34 @@ class DivMacroInt {
|
|||
dt(0),
|
||||
d2r(0),
|
||||
ssg(0),
|
||||
dam(0),
|
||||
dvb(0),
|
||||
egt(0),
|
||||
ksl(0),
|
||||
sus(0),
|
||||
vib(0),
|
||||
ws(0),
|
||||
ksr(0),
|
||||
hasAm(false), hasAr(false), hasDr(false), hasMult(false),
|
||||
hasRr(false), hasSl(false), hasTl(false), hasDt2(false),
|
||||
hasRs(false), hasDt(false), hasD2r(false), hasSsg(false),
|
||||
hasDam(false), hasDvb(false), hasEgt(false), hasKsl(false),
|
||||
hasSus(false), hasVib(false), hasWs(false), hasKsr(false),
|
||||
hadAm(false), hadAr(false), hadDr(false), hadMult(false),
|
||||
hadRr(false), hadSl(false), hadTl(false), hadDt2(false),
|
||||
hadRs(false), hadDt(false), hadD2r(false), hadSsg(false),
|
||||
hadDam(false), hadDvb(false), hadEgt(false), hadKsl(false),
|
||||
hadSus(false), hadVib(false), hadWs(false), hadKsr(false),
|
||||
finishedAm(false), finishedAr(false), finishedDr(false), finishedMult(false),
|
||||
finishedRr(false), finishedSl(false), finishedTl(false), finishedDt2(false),
|
||||
finishedRs(false), finishedDt(false), finishedD2r(false), finishedSsg(false),
|
||||
finishedDam(false), finishedDvb(false), finishedEgt(false), finishedKsl(false),
|
||||
finishedSus(false), finishedVib(false), finishedWs(false), finishedKsr(false),
|
||||
willAm(false), willAr(false), willDr(false), willMult(false),
|
||||
willRr(false), willSl(false), willTl(false), willDt2(false),
|
||||
willRs(false), willDt(false), willD2r(false), willSsg(false) {}
|
||||
willRs(false), willDt(false), willD2r(false), willSsg(false),
|
||||
willDam(false), willDvb(false), willEgt(false), willKsl(false),
|
||||
willSus(false), willVib(false), willWs(false), willKsr(false) {}
|
||||
} op[4];
|
||||
void release();
|
||||
void next();
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ void DivPlatformLynx::forceIns() {
|
|||
chan[i].insChanged=true;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
WRITE_ATTEN(i,chan[i].pan);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ const char* DivPlatformOPLL::getEffectName(unsigned char effect) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char cycleMapOPLL[18]={
|
||||
8, 7, 6, 7, 8, 7, 8, 6, 0, 1, 2, 7, 8, 9, 3, 4, 5, 9
|
||||
};
|
||||
|
||||
void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
static int o[2];
|
||||
static int os;
|
||||
|
|
@ -100,7 +104,10 @@ void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size
|
|||
}
|
||||
|
||||
OPLL_Clock(&fm,o);
|
||||
os+=(o[0]+o[1]);
|
||||
unsigned char nextOut=cycleMapOPLL[fm.cycles];
|
||||
if (!isMuted[nextOut]) {
|
||||
os+=(o[0]+o[1]);
|
||||
}
|
||||
}
|
||||
os*=50;
|
||||
if (os<-32768) os=-32768;
|
||||
|
|
@ -120,21 +127,9 @@ void DivPlatformOPLL::tick() {
|
|||
for (int i=0; i<9; i++) {
|
||||
chan[i].std.next();
|
||||
|
||||
/*if (chan[i].std.hadVol) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(127,chan[i].std.vol))/127;
|
||||
for (int j=0; j<4; j++) {
|
||||
unsigned short baseAddr=chanOffs[i]|opOffs[j];
|
||||
DivInstrumentFM::Operator& op=chan[i].state.op[j];
|
||||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[i].std.hadVol) {
|
||||
chan[i].outVol=(chan[i].vol*MIN(15,chan[i].std.vol))/15;
|
||||
rWrite(0x30+i,(15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)|(chan[i].state.opllPreset<<4));
|
||||
}
|
||||
|
||||
if (chan[i].std.hadArp) {
|
||||
|
|
@ -153,95 +148,86 @@ void DivPlatformOPLL::tick() {
|
|||
}
|
||||
}
|
||||
|
||||
if (chan[i].std.hadAlg) {
|
||||
chan[i].state.alg=chan[i].std.alg;
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
if (!parent->song.algMacroBehavior) for (int j=0; j<4; j++) {
|
||||
unsigned short baseAddr=chanOffs[i]|opOffs[j];
|
||||
if (chan[i].state.opllPreset==0) {
|
||||
if (chan[i].std.hadAlg) { // SUS
|
||||
chan[i].state.alg=chan[i].std.alg;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
if (chan[i].std.hadFb) {
|
||||
chan[i].state.fb=chan[i].std.fb;
|
||||
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
|
||||
}
|
||||
if (chan[i].std.hadFms) {
|
||||
chan[i].state.fms=chan[i].std.fms;
|
||||
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
|
||||
}
|
||||
if (chan[i].std.hadAms) {
|
||||
chan[i].state.ams=chan[i].std.ams;
|
||||
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
|
||||
}
|
||||
|
||||
for (int j=0; j<2; j++) {
|
||||
DivInstrumentFM::Operator& op=chan[i].state.op[j];
|
||||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127));
|
||||
DivMacroInt::IntOp& m=chan[i].std.op[j];
|
||||
|
||||
if (m.hadAm) {
|
||||
op.am=m.am;
|
||||
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
|
||||
}
|
||||
if (m.hadAr) {
|
||||
op.ar=m.ar;
|
||||
rWrite(0x04+j,(op.ar<<4)|(op.dr));
|
||||
}
|
||||
if (m.hadDr) {
|
||||
op.dr=m.dr;
|
||||
rWrite(0x04+j,(op.ar<<4)|(op.dr));
|
||||
}
|
||||
if (m.hadMult) {
|
||||
op.mult=m.mult;
|
||||
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
|
||||
}
|
||||
if (m.hadRr) {
|
||||
op.rr=m.rr;
|
||||
rWrite(0x06+j,(op.sl<<4)|(op.rr));
|
||||
}
|
||||
if (m.hadSl) {
|
||||
op.sl=m.sl;
|
||||
rWrite(0x06+j,(op.sl<<4)|(op.rr));
|
||||
}
|
||||
if (m.hadTl) {
|
||||
op.tl=((j==1)?15:63)-m.tl;
|
||||
if (j==1) {
|
||||
rWrite(0x30+i,(15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)|(chan[i].state.opllPreset<<4));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
rWrite(0x02,(chan[i].state.op[1].ksl<<6)|(op.tl&63));
|
||||
}
|
||||
}
|
||||
|
||||
if (m.hadEgt) {
|
||||
op.ssgEnv=(m.egt&1)?8:0;
|
||||
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
|
||||
}
|
||||
if (m.hadKsl) {
|
||||
op.ksl=m.ksl;
|
||||
if (j==1) {
|
||||
rWrite(0x02,(op.ksl<<6)|(chan[i].state.op[0].tl&63));
|
||||
} else {
|
||||
rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
|
||||
}
|
||||
}
|
||||
if (m.hadKsr) {
|
||||
op.ksr=m.ksr;
|
||||
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
|
||||
}
|
||||
if (m.hadVib) {
|
||||
op.vib=m.vib;
|
||||
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[i].std.hadFb) {
|
||||
chan[i].state.fb=chan[i].std.fb;
|
||||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
}
|
||||
if (chan[i].std.hadFms) {
|
||||
chan[i].state.fms=chan[i].std.fms;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
if (chan[i].std.hadAms) {
|
||||
chan[i].state.ams=chan[i].std.ams;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
for (int j=0; j<2; j++) {
|
||||
unsigned short baseAddr=chanOffs[i]|opOffs[j];
|
||||
DivInstrumentFM::Operator& op=chan[i].state.op[j];
|
||||
DivMacroInt::IntOp& m=chan[i].std.op[j];
|
||||
if (m.hadAm) {
|
||||
op.am=m.am;
|
||||
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||
}
|
||||
if (m.hadAr) {
|
||||
op.ar=m.ar;
|
||||
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||
}
|
||||
if (m.hadDr) {
|
||||
op.dr=m.dr;
|
||||
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||
}
|
||||
if (m.hadMult) {
|
||||
op.mult=m.mult;
|
||||
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||
}
|
||||
if (m.hadRr) {
|
||||
op.rr=m.rr;
|
||||
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||
}
|
||||
if (m.hadSl) {
|
||||
op.sl=m.sl;
|
||||
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||
}
|
||||
if (m.hadTl) {
|
||||
op.tl=127-m.tl;
|
||||
if (isMuted[i]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
} else {
|
||||
if (isOutput[chan[i].state.alg][j]) {
|
||||
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m.hadRs) {
|
||||
op.rs=m.rs;
|
||||
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||
}
|
||||
if (m.hadDt) {
|
||||
op.dt=m.dt;
|
||||
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||
}
|
||||
if (m.hadD2r) {
|
||||
op.d2r=m.d2r;
|
||||
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||
}
|
||||
if (m.hadSsg) {
|
||||
op.ssgEnv=m.ssg;
|
||||
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (chan[i].keyOn || chan[i].keyOff) {
|
||||
if (chan[i].drums) {
|
||||
if (i>=6 && drums) {
|
||||
drumState&=~(0x10>>(chan[i].note%12));
|
||||
immWrite(0x0e,0x20|drumState);
|
||||
} else {
|
||||
|
|
@ -266,11 +252,11 @@ void DivPlatformOPLL::tick() {
|
|||
int freqt=toFreq(chan[i].freq);
|
||||
chan[i].freqH=freqt>>8;
|
||||
chan[i].freqL=freqt&0xff;
|
||||
if (!chan[i].drums) {
|
||||
if (i<6 || !drums) {
|
||||
immWrite(0x10+i,freqt&0xff);
|
||||
}
|
||||
}
|
||||
if (chan[i].keyOn && chan[i].drums) {
|
||||
if (chan[i].keyOn && i>=6 && drums) {
|
||||
//printf("%d\n",chan[i].note%12);
|
||||
drumState|=(0x10>>(chan[i].note%12));
|
||||
immWrite(0x0e,0x20|drumState);
|
||||
|
|
@ -372,21 +358,27 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
rWrite(0x05,(car.ar<<4)|(car.dr));
|
||||
rWrite(0x06,(mod.sl<<4)|(mod.rr));
|
||||
rWrite(0x07,(car.sl<<4)|(car.rr));
|
||||
lastCustomMemory=c.chan;
|
||||
}
|
||||
if (chan[c.chan].state.opllPreset==16) { // compatible drums mode
|
||||
chan[c.chan].drums=true;
|
||||
immWrite(0x16,0x20);
|
||||
immWrite(0x26,0x05);
|
||||
immWrite(0x16,0x20);
|
||||
immWrite(0x26,0x05);
|
||||
immWrite(0x17,0x50);
|
||||
immWrite(0x27,0x05);
|
||||
immWrite(0x17,0x50);
|
||||
immWrite(0x27,0x05);
|
||||
immWrite(0x18,0xC0);
|
||||
immWrite(0x28,0x01);
|
||||
if (c.chan>=6) {
|
||||
drums=true;
|
||||
immWrite(0x16,0x20);
|
||||
immWrite(0x26,0x05);
|
||||
immWrite(0x16,0x20);
|
||||
immWrite(0x26,0x05);
|
||||
immWrite(0x17,0x50);
|
||||
immWrite(0x27,0x05);
|
||||
immWrite(0x17,0x50);
|
||||
immWrite(0x27,0x05);
|
||||
immWrite(0x18,0xC0);
|
||||
immWrite(0x28,0x01);
|
||||
}
|
||||
} else {
|
||||
chan[c.chan].drums=false;
|
||||
if (c.chan>=6) {
|
||||
drums=false;
|
||||
immWrite(0x0e,0);
|
||||
}
|
||||
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
||||
}
|
||||
}
|
||||
|
|
@ -397,7 +389,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
|
||||
chan[c.chan].note=c.value;
|
||||
|
||||
if (chan[c.chan].drums) {
|
||||
if (c.chan>=6 && drums) {
|
||||
switch (chan[c.chan].note%12) {
|
||||
case 0: // kick
|
||||
drumVol[0]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15);
|
||||
|
|
@ -444,7 +436,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
if (!chan[c.chan].std.hasVol) {
|
||||
chan[c.chan].outVol=c.value;
|
||||
}
|
||||
if (!chan[c.chan].drums) {
|
||||
if (c.chan<6 || !drums) {
|
||||
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
||||
}
|
||||
break;
|
||||
|
|
@ -502,52 +494,56 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case DIV_CMD_FM_FB: {
|
||||
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
|
||||
//DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
|
||||
chan[c.chan].state.fb=c.value&7;
|
||||
rWrite(chanOffs[c.chan]+ADDR_FB_ALG,(chan[c.chan].state.alg&7)|(chan[c.chan].state.fb<<3));
|
||||
rWrite(0x03,(mod.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb);
|
||||
break;
|
||||
}
|
||||
|
||||
case DIV_CMD_FM_MULT: {
|
||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||
op.mult=c.value2&15;
|
||||
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||
if (c.value==0) {
|
||||
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
|
||||
mod.mult=c.value2&15;
|
||||
rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
|
||||
} else {
|
||||
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
|
||||
car.mult=c.value2&15;
|
||||
rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_TL: {
|
||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||
op.tl=c.value2;
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(baseAddr+ADDR_TL,127);
|
||||
if (c.value==0) {
|
||||
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
|
||||
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
|
||||
mod.tl=c.value2&63;
|
||||
rWrite(0x02,(car.ksl<<6)|(mod.tl&63));
|
||||
} else {
|
||||
if (isOutput[chan[c.chan].state.alg][c.value]) {
|
||||
rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].outVol&0x7f))/127));
|
||||
} else {
|
||||
rWrite(baseAddr+ADDR_TL,op.tl);
|
||||
}
|
||||
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
|
||||
car.tl=c.value2&15;
|
||||
rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_FM_AR: {
|
||||
DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0];
|
||||
DivInstrumentFM::Operator& car=chan[c.chan].state.op[1];
|
||||
if (c.value<0) {
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||
op.ar=c.value2&31;
|
||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||
}
|
||||
mod.ar=c.value2&15;
|
||||
car.ar=c.value2&15;
|
||||
} else {
|
||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||
op.ar=c.value2&31;
|
||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||
if (c.value==0) {
|
||||
mod.ar=c.value2&15;
|
||||
} else {
|
||||
car.ar=c.value2&15;
|
||||
}
|
||||
}
|
||||
|
||||
rWrite(0x04,(mod.ar<<4)|(mod.dr));
|
||||
rWrite(0x05,(car.ar<<4)|(car.dr));
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
break;
|
||||
|
|
@ -569,7 +565,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
void DivPlatformOPLL::forceIns() {
|
||||
for (int i=0; i<9; i++) {
|
||||
// update custom preset
|
||||
if (chan[i].state.opllPreset==0) {
|
||||
if (chan[i].state.opllPreset==0 && i==lastCustomMemory) {
|
||||
DivInstrumentFM::Operator& mod=chan[i].state.op[0];
|
||||
DivInstrumentFM::Operator& car=chan[i].state.op[1];
|
||||
rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult));
|
||||
|
|
@ -587,12 +583,33 @@ void DivPlatformOPLL::forceIns() {
|
|||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
if (drums) {
|
||||
immWrite(0x16,0x20);
|
||||
immWrite(0x26,0x05);
|
||||
immWrite(0x16,0x20);
|
||||
immWrite(0x26,0x05);
|
||||
immWrite(0x17,0x50);
|
||||
immWrite(0x27,0x05);
|
||||
immWrite(0x17,0x50);
|
||||
immWrite(0x27,0x05);
|
||||
immWrite(0x18,0xC0);
|
||||
immWrite(0x28,0x01);
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::toggleRegisterDump(bool enable) {
|
||||
DivDispatch::toggleRegisterDump(enable);
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::setVRC7(bool vrc) {
|
||||
vrc7=vrc;
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::setProperDrums(bool pd) {
|
||||
properDrums=pd;
|
||||
}
|
||||
|
||||
|
||||
void* DivPlatformOPLL::getChanState(int ch) {
|
||||
return &chan[ch];
|
||||
}
|
||||
|
|
@ -608,7 +625,11 @@ int DivPlatformOPLL::getRegisterPoolSize() {
|
|||
void DivPlatformOPLL::reset() {
|
||||
while (!writes.empty()) writes.pop();
|
||||
memset(regPool,0,256);
|
||||
OPLL_Reset(&fm,opll_type_ym2413);
|
||||
if (vrc7) {
|
||||
OPLL_Reset(&fm,opll_type_ds1001);
|
||||
} else {
|
||||
OPLL_Reset(&fm,opll_type_ym2413);
|
||||
}
|
||||
if (dumpWrites) {
|
||||
addWrite(0xffffffff,0);
|
||||
}
|
||||
|
|
@ -625,6 +646,7 @@ void DivPlatformOPLL::reset() {
|
|||
|
||||
lastBusy=60;
|
||||
drumState=0;
|
||||
lastCustomMemory=-1;
|
||||
|
||||
drumVol[0]=0;
|
||||
drumVol[1]=0;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch, note;
|
||||
unsigned char ins;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, drums, portaPause, furnaceDac, inPorta;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
Channel():
|
||||
|
|
@ -51,15 +51,14 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
freqChanged(false),
|
||||
keyOn(false),
|
||||
keyOff(false),
|
||||
drums(false),
|
||||
portaPause(false),
|
||||
furnaceDac(false),
|
||||
inPorta(false),
|
||||
vol(0),
|
||||
pan(3) {}
|
||||
};
|
||||
Channel chan[9];
|
||||
bool isMuted[9];
|
||||
Channel chan[11];
|
||||
bool isMuted[11];
|
||||
struct QueuedWrite {
|
||||
unsigned short addr;
|
||||
unsigned char val;
|
||||
|
|
@ -68,7 +67,7 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
};
|
||||
std::queue<QueuedWrite> writes;
|
||||
opll_t fm;
|
||||
int delay;
|
||||
int delay, lastCustomMemory;
|
||||
unsigned char lastBusy;
|
||||
unsigned char drumState;
|
||||
unsigned char drumVol[5];
|
||||
|
|
@ -76,6 +75,9 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
unsigned char regPool[256];
|
||||
|
||||
bool useYMFM;
|
||||
bool drums;
|
||||
bool properDrums;
|
||||
bool vrc7;
|
||||
|
||||
short oldWrites[256];
|
||||
short pendingWrites[256];
|
||||
|
|
@ -102,6 +104,8 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
void toggleRegisterDump(bool enable);
|
||||
void setVRC7(bool vrc);
|
||||
void setProperDrums(bool pd);
|
||||
void setFlags(unsigned int flags);
|
||||
void notifyInsChange(int ins);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
|||
|
|
@ -226,4 +226,6 @@ void apu_turn_on(struct NESAPU* a, BYTE apu_type) {
|
|||
a->DMC.length = 1;
|
||||
a->DMC.address_start = 0xC000;
|
||||
a->apu.odd_cycle = 0;
|
||||
// come non viene inizializzato? Vorrei qualche spiegazione...
|
||||
a->r4011.frames = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,6 +373,39 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPLL:
|
||||
case DIV_SYSTEM_OPLL_DRUMS:
|
||||
case DIV_SYSTEM_VRC7:
|
||||
switch (effect) {
|
||||
case 0x11: // FB
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_FB,ch,effectVal&7));
|
||||
break;
|
||||
case 0x12: // TL op1
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,0,effectVal&0x3f));
|
||||
break;
|
||||
case 0x13: // TL op2
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,1,effectVal&0x0f));
|
||||
break;
|
||||
case 0x16: // MULT
|
||||
if ((effectVal>>4)>0 && (effectVal>>4)<3) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15));
|
||||
}
|
||||
break;
|
||||
case 0x18: // drum mode toggle
|
||||
break;
|
||||
case 0x19: // AR global
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&31));
|
||||
break;
|
||||
case 0x1a: // AR op1
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,0,effectVal&31));
|
||||
break;
|
||||
case 0x1b: // AR op2
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,1,effectVal&31));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580:
|
||||
switch (effect) {
|
||||
case 0x10: // select waveform
|
||||
|
|
|
|||
|
|
@ -680,9 +680,9 @@ const char* DivEngine::getSystemChips(DivSystem sys) {
|
|||
case DIV_SYSTEM_AMIGA:
|
||||
return "MOS 8364 Paula";
|
||||
case DIV_SYSTEM_YM2151:
|
||||
return "Yamaha YM2151 standalone";
|
||||
return "Yamaha YM2151";
|
||||
case DIV_SYSTEM_YM2612:
|
||||
return "Yamaha YM2612 standalone";
|
||||
return "Yamaha YM2612";
|
||||
case DIV_SYSTEM_TIA:
|
||||
return "Atari TIA";
|
||||
case DIV_SYSTEM_VIC20:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue