diff --git a/papers/format.md b/papers/format.md index cc4a5add..54414fa4 100644 --- a/papers/format.md +++ b/papers/format.md @@ -29,6 +29,8 @@ furthermore, an `or reserved` indicates this field is always present, but is res the format versions are: +- 76: Furnace dev76 +- 75: Furnace dev75/April Fools' 0.6pre0 - 74: Furnace dev74 - 73: Furnace dev73 - 72: Furnace dev72 @@ -523,6 +525,54 @@ size | description | - bit 1: update on change | - bit 0: load on playback 1 | reserved + --- | **even more macros** (>=76) + 4 | left panning macro length + 4 | right panning macro length + 4 | phase reset macro length + 4 | extra 4 macro length + 4 | extra 5 macro length + 4 | extra 6 macro length + 4 | extra 7 macro length + 4 | extra 8 macro length + 4 | left panning macro loop + 4 | right panning macro loop + 4 | phase reset macro loop + 4 | extra 4 macro loop + 4 | extra 5 macro loop + 4 | extra 6 macro loop + 4 | extra 7 macro loop + 4 | extra 8 macro loop + 4 | left panning macro release + 4 | right panning macro release + 4 | phase reset macro release + 4 | extra 4 macro release + 4 | extra 5 macro release + 4 | extra 6 macro release + 4 | extra 7 macro release + 4 | extra 8 macro release + 1 | left panning macro open + 1 | right panning macro open + 1 | phase reset macro open + 1 | extra 4 macro open + 1 | extra 5 macro open + 1 | extra 6 macro open + 1 | extra 7 macro open + 1 | extra 8 macro open + --- | **even more macro data** (>=76) + 4?? | left panning macro + 4?? | right panning macro + 4?? | phase reset macro + 4?? | extra 4 macro + 4?? | extra 5 macro + 4?? | extra 6 macro + 4?? | extra 7 macro + 4?? | extra 8 macro + --- | **FDS instrument data** (>=76) + 4 | modulation speed + 4 | modulation depth + 1 | init modulation table with first wave + 3 | reserved + 32 | modulation table ``` # wavetable diff --git a/src/engine/engine.h b/src/engine/engine.h index f4a3db83..9a15f4f1 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -42,8 +42,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev75" -#define DIV_ENGINE_VERSION 75 +#define DIV_VERSION "dev76" +#define DIV_ENGINE_VERSION 76 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index f3cf9f59..3dd1e883 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -392,6 +392,77 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeC(n163.waveLen); w->writeC(n163.waveMode); w->writeC(0); // reserved + + // more macros + w->writeI(std.panLMacroLen); + w->writeI(std.panRMacroLen); + w->writeI(std.phaseResetMacroLen); + w->writeI(std.ex4MacroLen); + w->writeI(std.ex5MacroLen); + w->writeI(std.ex6MacroLen); + w->writeI(std.ex7MacroLen); + w->writeI(std.ex8MacroLen); + + w->writeI(std.panLMacroLoop); + w->writeI(std.panRMacroLoop); + w->writeI(std.phaseResetMacroLoop); + w->writeI(std.ex4MacroLoop); + w->writeI(std.ex5MacroLoop); + w->writeI(std.ex6MacroLoop); + w->writeI(std.ex7MacroLoop); + w->writeI(std.ex8MacroLoop); + + w->writeI(std.panLMacroRel); + w->writeI(std.panRMacroRel); + w->writeI(std.phaseResetMacroRel); + w->writeI(std.ex4MacroRel); + w->writeI(std.ex5MacroRel); + w->writeI(std.ex6MacroRel); + w->writeI(std.ex7MacroRel); + w->writeI(std.ex8MacroRel); + + w->writeC(std.panLMacroOpen); + w->writeC(std.panRMacroOpen); + w->writeC(std.phaseResetMacroOpen); + w->writeC(std.ex4MacroOpen); + w->writeC(std.ex5MacroOpen); + w->writeC(std.ex6MacroOpen); + w->writeC(std.ex7MacroOpen); + w->writeC(std.ex8MacroOpen); + + for (int j=0; jwriteI(std.panLMacro[j]); + } + for (int j=0; jwriteI(std.panRMacro[j]); + } + for (int j=0; jwriteI(std.phaseResetMacro[j]); + } + for (int j=0; jwriteI(std.ex4Macro[j]); + } + for (int j=0; jwriteI(std.ex5Macro[j]); + } + for (int j=0; jwriteI(std.ex6Macro[j]); + } + for (int j=0; jwriteI(std.ex7Macro[j]); + } + for (int j=0; jwriteI(std.ex8Macro[j]); + } + + // FDS + w->writeI(fds.modSpeed); + w->writeI(fds.modDepth); + w->writeC(fds.initModTableWithFirstWave); + w->writeC(0); // reserved + w->writeC(0); + w->writeC(0); + w->write(fds.modTable,32); } DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { @@ -755,6 +826,65 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { n163.waveMode=(unsigned char)reader.readC(); reader.readC(); // reserved } + + // more macros + if (version>=76) { + std.panLMacroLen=reader.readI(); + std.panRMacroLen=reader.readI(); + std.phaseResetMacroLen=reader.readI(); + std.ex4MacroLen=reader.readI(); + std.ex5MacroLen=reader.readI(); + std.ex6MacroLen=reader.readI(); + std.ex7MacroLen=reader.readI(); + std.ex8MacroLen=reader.readI(); + + std.panLMacroLoop=reader.readI(); + std.panRMacroLoop=reader.readI(); + std.phaseResetMacroLoop=reader.readI(); + std.ex4MacroLoop=reader.readI(); + std.ex5MacroLoop=reader.readI(); + std.ex6MacroLoop=reader.readI(); + std.ex7MacroLoop=reader.readI(); + std.ex8MacroLoop=reader.readI(); + + std.panLMacroRel=reader.readI(); + std.panRMacroRel=reader.readI(); + std.phaseResetMacroRel=reader.readI(); + std.ex4MacroRel=reader.readI(); + std.ex5MacroRel=reader.readI(); + std.ex6MacroRel=reader.readI(); + std.ex7MacroRel=reader.readI(); + std.ex8MacroRel=reader.readI(); + + std.panLMacroOpen=reader.readC(); + std.panRMacroOpen=reader.readC(); + std.phaseResetMacroOpen=reader.readC(); + std.ex4MacroOpen=reader.readC(); + std.ex5MacroOpen=reader.readC(); + std.ex6MacroOpen=reader.readC(); + std.ex7MacroOpen=reader.readC(); + std.ex8MacroOpen=reader.readC(); + + reader.read(std.panLMacro,4*std.panLMacroLen); + reader.read(std.panRMacro,4*std.panRMacroLen); + reader.read(std.phaseResetMacro,4*std.phaseResetMacroLen); + reader.read(std.ex4Macro,4*std.ex4MacroLen); + reader.read(std.ex5Macro,4*std.ex5MacroLen); + reader.read(std.ex6Macro,4*std.ex6MacroLen); + reader.read(std.ex7Macro,4*std.ex7MacroLen); + reader.read(std.ex8Macro,4*std.ex8MacroLen); + } + + // FDS + if (version>=76) { + fds.modSpeed=reader.readI(); + fds.modDepth=reader.readI(); + fds.initModTableWithFirstWave=reader.readC(); + reader.readC(); // reserved + reader.readC(); + reader.readC(); + reader.read(fds.modTable,32); + } return DIV_DATA_SUCCESS; } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index e8ec9d31..fafd16b5 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -148,6 +148,7 @@ struct DivInstrumentFM { } }; +// this is getting out of hand struct DivInstrumentSTD { int volMacro[256]; int arpMacro[256]; @@ -161,20 +162,41 @@ struct DivInstrumentSTD { int fbMacro[256]; int fmsMacro[256]; int amsMacro[256]; + int panLMacro[256]; + int panRMacro[256]; + int phaseResetMacro[256]; + int ex4Macro[256]; + int ex5Macro[256]; + int ex6Macro[256]; + int ex7Macro[256]; + int ex8Macro[256]; + bool arpMacroMode; unsigned char volMacroHeight, dutyMacroHeight, waveMacroHeight; + bool volMacroOpen, arpMacroOpen, dutyMacroOpen, waveMacroOpen; bool pitchMacroOpen, ex1MacroOpen, ex2MacroOpen, ex3MacroOpen; bool algMacroOpen, fbMacroOpen, fmsMacroOpen, amsMacroOpen; + bool panLMacroOpen, panRMacroOpen, phaseResetMacroOpen, ex4MacroOpen; + bool ex5MacroOpen, ex6MacroOpen, ex7MacroOpen, ex8MacroOpen; + unsigned char volMacroLen, arpMacroLen, dutyMacroLen, waveMacroLen; unsigned char pitchMacroLen, ex1MacroLen, ex2MacroLen, ex3MacroLen; unsigned char algMacroLen, fbMacroLen, fmsMacroLen, amsMacroLen; + unsigned char panLMacroLen, panRMacroLen, phaseResetMacroLen, ex4MacroLen; + unsigned char ex5MacroLen, ex6MacroLen, ex7MacroLen, ex8MacroLen; + signed char volMacroLoop, arpMacroLoop, dutyMacroLoop, waveMacroLoop; signed char pitchMacroLoop, ex1MacroLoop, ex2MacroLoop, ex3MacroLoop; signed char algMacroLoop, fbMacroLoop, fmsMacroLoop, amsMacroLoop; + signed char panLMacroLoop, panRMacroLoop, phaseResetMacroLoop, ex4MacroLoop; + signed char ex5MacroLoop, ex6MacroLoop, ex7MacroLoop, ex8MacroLoop; + signed char volMacroRel, arpMacroRel, dutyMacroRel, waveMacroRel; signed char pitchMacroRel, ex1MacroRel, ex2MacroRel, ex3MacroRel; signed char algMacroRel, fbMacroRel, fmsMacroRel, amsMacroRel; + signed char panLMacroRel, panRMacroRel, phaseResetMacroRel, ex4MacroRel; + signed char ex5MacroRel, ex6MacroRel, ex7MacroRel, ex8MacroRel; struct OpMacro { // ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv; unsigned char amMacro[256]; @@ -277,6 +299,15 @@ struct DivInstrumentSTD { fbMacroOpen(false), fmsMacroOpen(false), amsMacroOpen(false), + panLMacroOpen(false), + panRMacroOpen(false), + phaseResetMacroOpen(false), + ex4MacroOpen(false), + ex5MacroOpen(false), + ex6MacroOpen(false), + ex7MacroOpen(false), + ex8MacroOpen(false), + volMacroLen(0), arpMacroLen(0), dutyMacroLen(0), @@ -289,6 +320,15 @@ struct DivInstrumentSTD { fbMacroLen(0), fmsMacroLen(0), amsMacroLen(0), + panLMacroLen(0), + panRMacroLen(0), + phaseResetMacroLen(0), + ex4MacroLen(0), + ex5MacroLen(0), + ex6MacroLen(0), + ex7MacroLen(0), + ex8MacroLen(0), + volMacroLoop(-1), arpMacroLoop(-1), dutyMacroLoop(-1), @@ -301,6 +341,15 @@ struct DivInstrumentSTD { fbMacroLoop(-1), fmsMacroLoop(-1), amsMacroLoop(-1), + panLMacroLoop(-1), + panRMacroLoop(-1), + phaseResetMacroLoop(-1), + ex4MacroLoop(-1), + ex5MacroLoop(-1), + ex6MacroLoop(-1), + ex7MacroLoop(-1), + ex8MacroLoop(-1), + volMacroRel(-1), arpMacroRel(-1), dutyMacroRel(-1), @@ -312,7 +361,15 @@ struct DivInstrumentSTD { algMacroRel(-1), fbMacroRel(-1), fmsMacroRel(-1), - amsMacroRel(-1) { + amsMacroRel(-1), + panLMacroRel(-1), + panRMacroRel(-1), + phaseResetMacroRel(-1), + ex4MacroRel(-1), + ex5MacroRel(-1), + ex6MacroRel(-1), + ex7MacroRel(-1), + ex8MacroRel(-1) { memset(volMacro,0,256*sizeof(int)); memset(arpMacro,0,256*sizeof(int)); memset(dutyMacro,0,256*sizeof(int)); @@ -325,6 +382,14 @@ struct DivInstrumentSTD { memset(fbMacro,0,256*sizeof(int)); memset(fmsMacro,0,256*sizeof(int)); memset(amsMacro,0,256*sizeof(int)); + memset(panLMacro,0,256*sizeof(int)); + memset(panRMacro,0,256*sizeof(int)); + memset(phaseResetMacro,0,256*sizeof(int)); + memset(ex4Macro,0,256*sizeof(int)); + memset(ex5Macro,0,256*sizeof(int)); + memset(ex6Macro,0,256*sizeof(int)); + memset(ex7Macro,0,256*sizeof(int)); + memset(ex8Macro,0,256*sizeof(int)); } }; @@ -399,10 +464,13 @@ struct DivInstrumentN163 { struct DivInstrumentFDS { signed char modTable[32]; - unsigned char modSpeed, modLevel; + int modSpeed, modDepth; + // this is here for compatibility. + bool initModTableWithFirstWave; DivInstrumentFDS(): modSpeed(0), - modLevel(0) { + modDepth(0), + initModTableWithFirstWave(false) { memset(modTable,0,32); } }; @@ -417,6 +485,7 @@ struct DivInstrument { DivInstrumentC64 c64; DivInstrumentAmiga amiga; DivInstrumentN163 n163; + DivInstrumentFDS fds; /** * save the instrument to a SafeWriter. diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index adcb3313..d74b59a6 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -63,6 +63,15 @@ void DivMacroInt::next() { doMacro(finishedFms,hadFms,hasFms,fms,fmsPos,ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,ins->std.fmsMacroRel); doMacro(finishedAms,hadAms,hasAms,ams,amsPos,ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop,ins->std.amsMacroRel); + doMacro(finishedPanL,hadPanL,hasPanL,panL,panLPos,ins->std.panLMacro,ins->std.panLMacroLen,ins->std.panLMacroLoop,ins->std.panLMacroRel); + doMacro(finishedPanR,hadPanR,hasPanR,panR,panRPos,ins->std.panRMacro,ins->std.panRMacroLen,ins->std.panRMacroLoop,ins->std.panRMacroRel); + doMacro(finishedPhaseReset,hadPhaseReset,hasPhaseReset,phaseReset,phaseResetPos,ins->std.phaseResetMacro,ins->std.phaseResetMacroLen,ins->std.phaseResetMacroLoop,ins->std.phaseResetMacroRel); + doMacro(finishedEx4,hadEx4,hasEx4,ex4,ex4Pos,ins->std.ex4Macro,ins->std.ex4MacroLen,ins->std.ex4MacroLoop,ins->std.ex4MacroRel); + doMacro(finishedEx5,hadEx5,hasEx5,ex5,ex5Pos,ins->std.ex5Macro,ins->std.ex5MacroLen,ins->std.ex5MacroLoop,ins->std.ex5MacroRel); + doMacro(finishedEx6,hadEx6,hasEx6,ex6,ex6Pos,ins->std.ex6Macro,ins->std.ex6MacroLen,ins->std.ex6MacroLoop,ins->std.ex6MacroRel); + doMacro(finishedEx7,hadEx7,hasEx7,ex7,ex7Pos,ins->std.ex7Macro,ins->std.ex7MacroLen,ins->std.ex7MacroLoop,ins->std.ex7MacroRel); + doMacro(finishedEx8,hadEx8,hasEx8,ex8,ex8Pos,ins->std.ex8Macro,ins->std.ex8MacroLen,ins->std.ex8MacroLoop,ins->std.ex8MacroRel); + for (int i=0; i<4; i++) { DivInstrumentSTD::OpMacro& m=ins->std.opMacros[i]; IntOp& o=op[i]; @@ -111,6 +120,14 @@ void DivMacroInt::init(DivInstrument* which) { fbPos=0; fmsPos=0; amsPos=0; + panLPos=0; + panRPos=0; + phaseResetPos=0; + ex4Pos=0; + ex5Pos=0; + ex6Pos=0; + ex7Pos=0; + ex8Pos=0; released=false; @@ -126,6 +143,14 @@ void DivMacroInt::init(DivInstrument* which) { hasFb=false; hasFms=false; hasAms=false; + hasPanL=false; + hasPanR=false; + hasPhaseReset=false; + hasEx4=false; + hasEx5=false; + hasEx6=false; + hasEx7=false; + hasEx8=false; hadVol=false; hadArp=false; @@ -139,6 +164,14 @@ void DivMacroInt::init(DivInstrument* which) { hadFb=false; hadFms=false; hadAms=false; + hadPanL=false; + hadPanR=false; + hadPhaseReset=false; + hadEx4=false; + hadEx5=false; + hadEx6=false; + hadEx7=false; + hadEx8=false; willVol=false; willArp=false; @@ -152,6 +185,14 @@ void DivMacroInt::init(DivInstrument* which) { willFb=false; willFms=false; willAms=false; + willPanL=false; + willPanR=false; + willPhaseReset=false; + willEx4=false; + willEx5=false; + willEx6=false; + willEx7=false; + willEx8=false; op[0]=IntOp(); op[1]=IntOp(); @@ -223,6 +264,48 @@ void DivMacroInt::init(DivInstrument* which) { willAms=true; } + // TODO: other macros + if (ins->std.panLMacroLen>0) { + hadPanL=true; + hasPanL=true; + willPanL=true; + } + if (ins->std.panRMacroLen>0) { + hadPanR=true; + hasPanR=true; + willPanR=true; + } + if (ins->std.phaseResetMacroLen>0) { + hadPhaseReset=true; + hasPhaseReset=true; + willPhaseReset=true; + } + if (ins->std.ex4MacroLen>0) { + hadEx4=true; + hasEx4=true; + willEx4=true; + } + if (ins->std.ex5MacroLen>0) { + hadEx5=true; + hasEx5=true; + willEx5=true; + } + if (ins->std.ex6MacroLen>0) { + hadEx6=true; + hasEx6=true; + willEx6=true; + } + if (ins->std.ex7MacroLen>0) { + hadEx7=true; + hasEx7=true; + willEx7=true; + } + if (ins->std.ex8MacroLen>0) { + hadEx8=true; + hasEx8=true; + willEx8=true; + } + if (ins->std.arpMacroMode) { arpMode=true; } @@ -339,4 +422,4 @@ void DivMacroInt::notifyInsDeletion(DivInstrument* which) { if (ins==which) { init(NULL); } -} \ No newline at end of file +} diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index b2b3c683..d5e6fd14 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -26,17 +26,23 @@ class DivMacroInt { DivInstrument* ins; int volPos, arpPos, dutyPos, wavePos, pitchPos, ex1Pos, ex2Pos, ex3Pos; int algPos, fbPos, fmsPos, amsPos; + int panLPos, panRPos, phaseResetPos, ex4Pos, ex5Pos, ex6Pos, ex7Pos, ex8Pos; bool released; public: int vol; int arp; int duty, wave, pitch, ex1, ex2, ex3; int alg, fb, fms, ams; + int panL, panR, phaseReset, ex4, ex5, ex6, ex7, ex8; bool hasVol, hasArp, hasDuty, hasWave, hasPitch, hasEx1, hasEx2, hasEx3, hasAlg, hasFb, hasFms, hasAms; + bool hasPanL, hasPanR, hasPhaseReset, hasEx4, hasEx5, hasEx6, hasEx7, hasEx8; bool hadVol, hadArp, hadDuty, hadWave, hadPitch, hadEx1, hadEx2, hadEx3, hadAlg, hadFb, hadFms, hadAms; + bool hadPanL, hadPanR, hadPhaseReset, hadEx4, hadEx5, hadEx6, hadEx7, hadEx8; bool finishedVol, finishedArp, finishedDuty, finishedWave, finishedPitch, finishedEx1, finishedEx2, finishedEx3; bool finishedAlg, finishedFb, finishedFms, finishedAms; + bool finishedPanL, finishedPanR, finishedPhaseReset, finishedEx4, finishedEx5, finishedEx6, finishedEx7, finishedEx8; bool willVol, willArp, willDuty, willWave, willPitch, willEx1, willEx2, willEx3, willAlg, willFb, willFms, willAms; + bool willPanL, willPanR, willPhaseReset, willEx4, willEx5, willEx6, willEx7, willEx8; bool arpMode; struct IntOp { int amPos, arPos, drPos, multPos; @@ -173,6 +179,14 @@ class DivMacroInt { fbPos(0), fmsPos(0), amsPos(0), + panLPos(0), + panRPos(0), + phaseResetPos(0), + ex4Pos(0), + ex5Pos(0), + ex6Pos(0), + ex7Pos(0), + ex8Pos(0), released(false), vol(0), arp(0), @@ -186,6 +200,14 @@ class DivMacroInt { fb(0), fms(0), ams(0), + panL(0), + panR(0), + phaseReset(0), + ex4(0), + ex5(0), + ex6(0), + ex7(0), + ex8(0), hasVol(false), hasArp(false), hasDuty(false), @@ -198,6 +220,14 @@ class DivMacroInt { hasFb(false), hasFms(false), hasAms(false), + hasPanL(false), + hasPanR(false), + hasPhaseReset(false), + hasEx4(false), + hasEx5(false), + hasEx6(false), + hasEx7(false), + hasEx8(false), hadVol(false), hadArp(false), hadDuty(false), @@ -210,6 +240,14 @@ class DivMacroInt { hadFb(false), hadFms(false), hadAms(false), + hadPanL(false), + hadPanR(false), + hadPhaseReset(false), + hadEx4(false), + hadEx5(false), + hadEx6(false), + hadEx7(false), + hadEx8(false), finishedVol(false), finishedArp(false), finishedDuty(false), @@ -222,6 +260,14 @@ class DivMacroInt { finishedFb(false), finishedFms(false), finishedAms(false), + finishedPanL(false), + finishedPanR(false), + finishedPhaseReset(false), + finishedEx4(false), + finishedEx5(false), + finishedEx6(false), + finishedEx7(false), + finishedEx8(false), willVol(false), willArp(false), willDuty(false), @@ -234,6 +280,14 @@ class DivMacroInt { willFb(false), willFms(false), willAms(false), + willPanL(false), + willPanR(false), + willPhaseReset(false), + willEx4(false), + willEx5(false), + willEx6(false), + willEx7(false), + willEx8(false), arpMode(false) {} };