mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-15 17:25:06 +00:00
parent
8991fa98ba
commit
4ce116ca0a
10 changed files with 278 additions and 90 deletions
|
@ -25,10 +25,12 @@ furthermore, an `or reserved` indicates this field is always present, but is res
|
|||
|
||||
the format versions are:
|
||||
|
||||
- 42: Furnace 0.5.5pre1
|
||||
- 41: Furnace 0.5.4
|
||||
- 40: Furnace 0.5.3
|
||||
- 39: Furnace 0.5.2
|
||||
- 44: Furnace 0.5.5pre2
|
||||
- 43: Furnace 0.5.5pre1
|
||||
- 42: Furnace 0.5.4
|
||||
- 41: Furnace 0.5.3
|
||||
- 40: Furnace 0.5.2
|
||||
- 39: Furnace 0.5.2pre3
|
||||
- 38: Furnace 0.5.2pre2
|
||||
- 37: Furnace 0.5.2pre1
|
||||
- 36: Furnace 0.5.1
|
||||
|
@ -353,6 +355,32 @@ size | description
|
|||
1?? | DT macro
|
||||
1?? | D2R macro
|
||||
1?? | SSG-EG macro
|
||||
--- | **release points** (>=44)
|
||||
4 | volume macro release
|
||||
4 | arp macro release
|
||||
4 | duty macro release
|
||||
4 | wave macro release
|
||||
4 | pitch macro release
|
||||
4 | extra 1 macro release
|
||||
4 | extra 2 macro release
|
||||
4 | extra 3 macro release
|
||||
4 | alg macro release
|
||||
4 | fb macro release
|
||||
4 | fms macro release
|
||||
4 | ams macro release
|
||||
--- | **operator release points** × 4 (>=44)
|
||||
4 | AM macro release
|
||||
4 | AR macro release
|
||||
4 | DR macro release
|
||||
4 | MULT macro release
|
||||
4 | RR macro release
|
||||
4 | SL macro release
|
||||
4 | TL macro release
|
||||
4 | DT2 macro release
|
||||
4 | RS macro release
|
||||
4 | DT macro release
|
||||
4 | D2R macro release
|
||||
4 | SSG-EG macro release
|
||||
|
||||
# wavetable
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
enum DivDispatchCmds {
|
||||
DIV_CMD_NOTE_ON=0,
|
||||
DIV_CMD_NOTE_OFF,
|
||||
DIV_CMD_NOTE_OFF_ENV,
|
||||
DIV_CMD_ENV_RELEASE,
|
||||
DIV_CMD_INSTRUMENT,
|
||||
DIV_CMD_VOLUME,
|
||||
DIV_CMD_GET_VOLUME,
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include <map>
|
||||
#include <queue>
|
||||
|
||||
#define DIV_VERSION "0.5.5pre1"
|
||||
#define DIV_ENGINE_VERSION 43
|
||||
#define DIV_VERSION "0.5.5pre2"
|
||||
#define DIV_ENGINE_VERSION 44
|
||||
|
||||
enum DivStatusView {
|
||||
DIV_STATUS_NOTHING=0,
|
||||
|
|
|
@ -253,6 +253,36 @@ void DivInstrument::putInsData(SafeWriter* w) {
|
|||
w->writeC(op.ssgMacro[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// release points
|
||||
w->writeI(std.volMacroRel);
|
||||
w->writeI(std.arpMacroRel);
|
||||
w->writeI(std.dutyMacroRel);
|
||||
w->writeI(std.waveMacroRel);
|
||||
w->writeI(std.pitchMacroRel);
|
||||
w->writeI(std.ex1MacroRel);
|
||||
w->writeI(std.ex2MacroRel);
|
||||
w->writeI(std.ex3MacroRel);
|
||||
w->writeI(std.algMacroRel);
|
||||
w->writeI(std.fbMacroRel);
|
||||
w->writeI(std.fmsMacroRel);
|
||||
w->writeI(std.amsMacroRel);
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
|
||||
|
||||
w->writeI(op.amMacroRel);
|
||||
w->writeI(op.arMacroRel);
|
||||
w->writeI(op.drMacroRel);
|
||||
w->writeI(op.multMacroRel);
|
||||
w->writeI(op.rrMacroRel);
|
||||
w->writeI(op.slMacroRel);
|
||||
w->writeI(op.tlMacroRel);
|
||||
w->writeI(op.dt2MacroRel);
|
||||
w->writeI(op.rsMacroRel);
|
||||
w->writeI(op.dtMacroRel);
|
||||
w->writeI(op.d2rMacroRel);
|
||||
w->writeI(op.ssgMacroRel);
|
||||
}
|
||||
}
|
||||
|
||||
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||
|
@ -484,6 +514,39 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
|||
}
|
||||
}
|
||||
|
||||
// release points
|
||||
if (version>=44) {
|
||||
std.volMacroRel=reader.readI();
|
||||
std.arpMacroRel=reader.readI();
|
||||
std.dutyMacroRel=reader.readI();
|
||||
std.waveMacroRel=reader.readI();
|
||||
std.pitchMacroRel=reader.readI();
|
||||
std.ex1MacroRel=reader.readI();
|
||||
std.ex2MacroRel=reader.readI();
|
||||
std.ex3MacroRel=reader.readI();
|
||||
std.algMacroRel=reader.readI();
|
||||
std.fbMacroRel=reader.readI();
|
||||
std.fmsMacroRel=reader.readI();
|
||||
std.amsMacroRel=reader.readI();
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
|
||||
|
||||
op.amMacroRel=reader.readI();
|
||||
op.arMacroRel=reader.readI();
|
||||
op.drMacroRel=reader.readI();
|
||||
op.multMacroRel=reader.readI();
|
||||
op.rrMacroRel=reader.readI();
|
||||
op.slMacroRel=reader.readI();
|
||||
op.tlMacroRel=reader.readI();
|
||||
op.dt2MacroRel=reader.readI();
|
||||
op.rsMacroRel=reader.readI();
|
||||
op.dtMacroRel=reader.readI();
|
||||
op.d2rMacroRel=reader.readI();
|
||||
op.ssgMacroRel=reader.readI();
|
||||
}
|
||||
}
|
||||
|
||||
return DIV_DATA_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ struct DivInstrumentSTD {
|
|||
signed char volMacroLoop, arpMacroLoop, dutyMacroLoop, waveMacroLoop;
|
||||
signed char pitchMacroLoop, ex1MacroLoop, ex2MacroLoop, ex3MacroLoop;
|
||||
signed char algMacroLoop, fbMacroLoop, fmsMacroLoop, amsMacroLoop;
|
||||
signed char volMacroRel, arpMacroRel, dutyMacroRel, waveMacroRel;
|
||||
signed char pitchMacroRel, ex1MacroRel, ex2MacroRel, ex3MacroRel;
|
||||
signed char algMacroRel, fbMacroRel, fmsMacroRel, amsMacroRel;
|
||||
struct OpMacro {
|
||||
// ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
||||
unsigned char amMacro[256];
|
||||
|
@ -146,6 +149,9 @@ struct DivInstrumentSTD {
|
|||
signed char amMacroLoop, arMacroLoop, drMacroLoop, multMacroLoop;
|
||||
signed char rrMacroLoop, slMacroLoop, tlMacroLoop, dt2MacroLoop;
|
||||
signed char rsMacroLoop, dtMacroLoop, d2rMacroLoop, ssgMacroLoop;
|
||||
signed char amMacroRel, arMacroRel, drMacroRel, multMacroRel;
|
||||
signed char rrMacroRel, slMacroRel, tlMacroRel, dt2MacroRel;
|
||||
signed char rsMacroRel, dtMacroRel, d2rMacroRel, ssgMacroRel;
|
||||
OpMacro():
|
||||
amMacroOpen(false), arMacroOpen(false), drMacroOpen(false), multMacroOpen(false),
|
||||
rrMacroOpen(false), slMacroOpen(false), tlMacroOpen(true), dt2MacroOpen(false),
|
||||
|
@ -155,7 +161,10 @@ struct DivInstrumentSTD {
|
|||
rsMacroLen(0), dtMacroLen(0), d2rMacroLen(0), ssgMacroLen(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) {
|
||||
rsMacroLoop(-1), dtMacroLoop(-1), d2rMacroLoop(-1), ssgMacroLoop(-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) {
|
||||
memset(amMacro,0,256);
|
||||
memset(arMacro,0,256);
|
||||
memset(drMacro,0,256);
|
||||
|
@ -210,7 +219,19 @@ struct DivInstrumentSTD {
|
|||
algMacroLoop(-1),
|
||||
fbMacroLoop(-1),
|
||||
fmsMacroLoop(-1),
|
||||
amsMacroLoop(-1) {
|
||||
amsMacroLoop(-1),
|
||||
volMacroRel(-1),
|
||||
arpMacroRel(-1),
|
||||
dutyMacroRel(-1),
|
||||
waveMacroRel(-1),
|
||||
pitchMacroRel(-1),
|
||||
ex1MacroRel(-1),
|
||||
ex2MacroRel(-1),
|
||||
ex3MacroRel(-1),
|
||||
algMacroRel(-1),
|
||||
fbMacroRel(-1),
|
||||
fmsMacroRel(-1),
|
||||
amsMacroRel(-1) {
|
||||
memset(volMacro,0,256*sizeof(int));
|
||||
memset(arpMacro,0,256*sizeof(int));
|
||||
memset(dutyMacro,0,256*sizeof(int));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "macroInt.h"
|
||||
#include "instrument.h"
|
||||
|
||||
#define doMacro(finished,had,has,val,pos,source,sourceLen,sourceLoop) \
|
||||
#define doMacro(finished,had,has,val,pos,source,sourceLen,sourceLoop,sourceRel) \
|
||||
if (finished) finished=false; \
|
||||
if (had!=has) { \
|
||||
finished=true; \
|
||||
|
@ -9,6 +9,9 @@
|
|||
had=has; \
|
||||
if (has) { \
|
||||
val=source[pos++]; \
|
||||
if (pos==sourceRel && !released) { \
|
||||
pos--; \
|
||||
} \
|
||||
if (pos>=sourceLen) { \
|
||||
if (sourceLoop<sourceLen && sourceLoop>=0) { \
|
||||
pos=sourceLoop; \
|
||||
|
@ -21,41 +24,45 @@
|
|||
void DivMacroInt::next() {
|
||||
if (ins==NULL) return;
|
||||
|
||||
doMacro(finishedVol,hadVol,hasVol,vol,volPos,ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop);
|
||||
doMacro(finishedArp,hadArp,hasArp,arp,arpPos,ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop);
|
||||
doMacro(finishedDuty,hadDuty,hasDuty,duty,dutyPos,ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop);
|
||||
doMacro(finishedWave,hadWave,hasWave,wave,wavePos,ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop);
|
||||
doMacro(finishedVol,hadVol,hasVol,vol,volPos,ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop,ins->std.volMacroRel);
|
||||
doMacro(finishedArp,hadArp,hasArp,arp,arpPos,ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,ins->std.arpMacroRel);
|
||||
doMacro(finishedDuty,hadDuty,hasDuty,duty,dutyPos,ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop,ins->std.dutyMacroRel);
|
||||
doMacro(finishedWave,hadWave,hasWave,wave,wavePos,ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel);
|
||||
|
||||
doMacro(finishedPitch,hadPitch,hasPitch,pitch,pitchPos,ins->std.pitchMacro,ins->std.pitchMacroLen,ins->std.pitchMacroLoop);
|
||||
doMacro(finishedEx1,hadEx1,hasEx1,ex1,ex1Pos,ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop);
|
||||
doMacro(finishedEx2,hadEx2,hasEx2,ex2,ex2Pos,ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop);
|
||||
doMacro(finishedEx3,hadEx3,hasEx3,ex3,ex3Pos,ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop);
|
||||
doMacro(finishedPitch,hadPitch,hasPitch,pitch,pitchPos,ins->std.pitchMacro,ins->std.pitchMacroLen,ins->std.pitchMacroLoop,ins->std.pitchMacroRel);
|
||||
doMacro(finishedEx1,hadEx1,hasEx1,ex1,ex1Pos,ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel);
|
||||
doMacro(finishedEx2,hadEx2,hasEx2,ex2,ex2Pos,ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,ins->std.ex2MacroRel);
|
||||
doMacro(finishedEx3,hadEx3,hasEx3,ex3,ex3Pos,ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,ins->std.ex3MacroRel);
|
||||
|
||||
doMacro(finishedAlg,hadAlg,hasAlg,alg,algPos,ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop);
|
||||
doMacro(finishedFb,hadFb,hasFb,fb,fbPos,ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop);
|
||||
doMacro(finishedFms,hadFms,hasFms,fms,fmsPos,ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop);
|
||||
doMacro(finishedAms,hadAms,hasAms,ams,amsPos,ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop);
|
||||
doMacro(finishedAlg,hadAlg,hasAlg,alg,algPos,ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,ins->std.algMacroRel);
|
||||
doMacro(finishedFb,hadFb,hasFb,fb,fbPos,ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,ins->std.fbMacroRel);
|
||||
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);
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentSTD::OpMacro& m=ins->std.opMacros[i];
|
||||
IntOp& o=op[i];
|
||||
doMacro(o.finishedAm,o.hadAm,o.hasAm,o.am,o.amPos,m.amMacro,m.amMacroLen,m.amMacroLoop);
|
||||
doMacro(o.finishedAr,o.hadAr,o.hasAr,o.ar,o.arPos,m.arMacro,m.arMacroLen,m.arMacroLoop);
|
||||
doMacro(o.finishedDr,o.hadDr,o.hasDr,o.dr,o.drPos,m.drMacro,m.drMacroLen,m.drMacroLoop);
|
||||
doMacro(o.finishedMult,o.hadMult,o.hasMult,o.mult,o.multPos,m.multMacro,m.multMacroLen,m.multMacroLoop);
|
||||
doMacro(o.finishedAm,o.hadAm,o.hasAm,o.am,o.amPos,m.amMacro,m.amMacroLen,m.amMacroLoop,m.amMacroRel);
|
||||
doMacro(o.finishedAr,o.hadAr,o.hasAr,o.ar,o.arPos,m.arMacro,m.arMacroLen,m.arMacroLoop,m.arMacroRel);
|
||||
doMacro(o.finishedDr,o.hadDr,o.hasDr,o.dr,o.drPos,m.drMacro,m.drMacroLen,m.drMacroLoop,m.drMacroRel);
|
||||
doMacro(o.finishedMult,o.hadMult,o.hasMult,o.mult,o.multPos,m.multMacro,m.multMacroLen,m.multMacroLoop,m.multMacroRel);
|
||||
|
||||
doMacro(o.finishedRr,o.hadRr,o.hasRr,o.rr,o.rrPos,m.rrMacro,m.rrMacroLen,m.rrMacroLoop);
|
||||
doMacro(o.finishedSl,o.hadSl,o.hasSl,o.sl,o.slPos,m.slMacro,m.slMacroLen,m.slMacroLoop);
|
||||
doMacro(o.finishedTl,o.hadTl,o.hasTl,o.tl,o.tlPos,m.tlMacro,m.tlMacroLen,m.tlMacroLoop);
|
||||
doMacro(o.finishedDt2,o.hadDt2,o.hasDt2,o.dt2,o.dt2Pos,m.dt2Macro,m.dt2MacroLen,m.dt2MacroLoop);
|
||||
doMacro(o.finishedRr,o.hadRr,o.hasRr,o.rr,o.rrPos,m.rrMacro,m.rrMacroLen,m.rrMacroLoop,m.rrMacroRel);
|
||||
doMacro(o.finishedSl,o.hadSl,o.hasSl,o.sl,o.slPos,m.slMacro,m.slMacroLen,m.slMacroLoop,m.slMacroRel);
|
||||
doMacro(o.finishedTl,o.hadTl,o.hasTl,o.tl,o.tlPos,m.tlMacro,m.tlMacroLen,m.tlMacroLoop,m.tlMacroRel);
|
||||
doMacro(o.finishedDt2,o.hadDt2,o.hasDt2,o.dt2,o.dt2Pos,m.dt2Macro,m.dt2MacroLen,m.dt2MacroLoop,m.dt2MacroRel);
|
||||
|
||||
doMacro(o.finishedRs,o.hadRs,o.hasRs,o.rs,o.rsPos,m.rsMacro,m.rsMacroLen,m.rsMacroLoop);
|
||||
doMacro(o.finishedDt,o.hadDt,o.hasDt,o.dt,o.dtPos,m.dtMacro,m.dtMacroLen,m.dtMacroLoop);
|
||||
doMacro(o.finishedD2r,o.hadD2r,o.hasD2r,o.d2r,o.d2rPos,m.d2rMacro,m.d2rMacroLen,m.d2rMacroLoop);
|
||||
doMacro(o.finishedSsg,o.hadSsg,o.hasSsg,o.ssg,o.ssgPos,m.ssgMacro,m.ssgMacroLen,m.ssgMacroLoop);
|
||||
doMacro(o.finishedRs,o.hadRs,o.hasRs,o.rs,o.rsPos,m.rsMacro,m.rsMacroLen,m.rsMacroLoop,m.rsMacroRel);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void DivMacroInt::release() {
|
||||
released=true;
|
||||
}
|
||||
|
||||
void DivMacroInt::init(DivInstrument* which) {
|
||||
ins=which;
|
||||
volPos=0;
|
||||
|
@ -71,6 +78,8 @@ void DivMacroInt::init(DivInstrument* which) {
|
|||
fmsPos=0;
|
||||
amsPos=0;
|
||||
|
||||
released=false;
|
||||
|
||||
hasVol=false;
|
||||
hasArp=false;
|
||||
hasDuty=false;
|
||||
|
|
|
@ -7,6 +7,7 @@ class DivMacroInt {
|
|||
DivInstrument* ins;
|
||||
int volPos, arpPos, dutyPos, wavePos, pitchPos, ex1Pos, ex2Pos, ex3Pos;
|
||||
int algPos, fbPos, fmsPos, amsPos;
|
||||
bool released;
|
||||
public:
|
||||
int vol;
|
||||
int arp;
|
||||
|
@ -80,6 +81,7 @@ class DivMacroInt {
|
|||
willRr(false), willSl(false), willTl(false), willDt2(false),
|
||||
willRs(false), willDt(false), willD2r(false), willSsg(false) {}
|
||||
} op[4];
|
||||
void release();
|
||||
void next();
|
||||
void init(DivInstrument* which);
|
||||
void notifyInsDeletion(DivInstrument* which);
|
||||
|
@ -97,6 +99,7 @@ class DivMacroInt {
|
|||
fbPos(0),
|
||||
fmsPos(0),
|
||||
amsPos(0),
|
||||
released(false),
|
||||
vol(0),
|
||||
arp(0),
|
||||
duty(0),
|
||||
|
|
|
@ -25,6 +25,8 @@ const char* notes[12]={
|
|||
const char* cmdName[DIV_CMD_MAX]={
|
||||
"NOTE_ON",
|
||||
"NOTE_OFF",
|
||||
"NOTE_OFF_ENV",
|
||||
"ENV_RELEASE",
|
||||
"INSTRUMENT",
|
||||
"VOLUME",
|
||||
"GET_VOLUME",
|
||||
|
@ -95,6 +97,10 @@ const char* formatNote(unsigned char note, unsigned char octave) {
|
|||
static char ret[4];
|
||||
if (note==100) {
|
||||
return "OFF";
|
||||
} else if (note==101) {
|
||||
return "===";
|
||||
} else if (note==102) {
|
||||
return "REL";
|
||||
} else if (octave==0 && note==0) {
|
||||
return "---";
|
||||
}
|
||||
|
@ -456,7 +462,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,i,pat->data[whatRow][2]));
|
||||
}
|
||||
// note
|
||||
if (pat->data[whatRow][0]==100) {
|
||||
if (pat->data[whatRow][0]==100) { // note off
|
||||
//chan[i].note=-1;
|
||||
chan[i].keyOn=false;
|
||||
chan[i].keyOff=true;
|
||||
|
@ -477,6 +483,29 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
chan[i].scheduledSlideReset=true;
|
||||
}
|
||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i));
|
||||
} else if (pat->data[whatRow][0]==101) { // note off + env release
|
||||
//chan[i].note=-1;
|
||||
chan[i].keyOn=false;
|
||||
chan[i].keyOff=true;
|
||||
if (chan[i].inPorta) {
|
||||
if (chan[i].stopOnOff) {
|
||||
chan[i].portaNote=-1;
|
||||
chan[i].portaSpeed=-1;
|
||||
chan[i].stopOnOff=false;
|
||||
}
|
||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||
chan[i].portaNote=-1;
|
||||
chan[i].portaSpeed=-1;
|
||||
if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||
chan[i+1].portaNote=-1;
|
||||
chan[i+1].portaSpeed=-1;
|
||||
}
|
||||
}
|
||||
chan[i].scheduledSlideReset=true;
|
||||
}
|
||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF_ENV,i));
|
||||
} else if (pat->data[whatRow][0]==102) { // env release
|
||||
dispatchCmd(DivCommand(DIV_CMD_ENV_RELEASE,i));
|
||||
} else if (!(pat->data[whatRow][0]==0 && pat->data[whatRow][1]==0)) {
|
||||
chan[i].oldNote=chan[i].note;
|
||||
chan[i].note=pat->data[whatRow][0]+((signed char)pat->data[whatRow][1])*12;
|
||||
|
|
137
src/gui/gui.cpp
137
src/gui/gui.cpp
|
@ -153,8 +153,12 @@ void FurnaceGUI::bindEngine(DivEngine* eng) {
|
|||
}
|
||||
|
||||
const char* noteNameNormal(short note, short octave) {
|
||||
if (note==100) {
|
||||
if (note==100) { // note cut
|
||||
return "OFF";
|
||||
} else if (note==101) { // note off and envelope release
|
||||
return "===";
|
||||
} else if (note==102) { // envelope release only
|
||||
return "REL";
|
||||
} else if (octave==0 && note==0) {
|
||||
return "...";
|
||||
}
|
||||
|
@ -168,6 +172,10 @@ const char* noteNameNormal(short note, short octave) {
|
|||
const char* FurnaceGUI::noteName(short note, short octave) {
|
||||
if (note==100) {
|
||||
return "OFF";
|
||||
} else if (note==101) { // note off and envelope release
|
||||
return "===";
|
||||
} else if (note==102) { // envelope release only
|
||||
return "REL";
|
||||
} else if (octave==0 && note==0) {
|
||||
return "...";
|
||||
}
|
||||
|
@ -211,11 +219,12 @@ bool FurnaceGUI::decodeNote(const char* what, short& note, short& octave) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void FurnaceGUI::encodeMMLStr(String& target, unsigned char* macro, unsigned char macroLen, signed char macroLoop) {
|
||||
void FurnaceGUI::encodeMMLStr(String& target, unsigned char* macro, unsigned char macroLen, signed char macroLoop, signed char macroRel) {
|
||||
target="";
|
||||
char buf[32];
|
||||
for (int i=0; i<macroLen; i++) {
|
||||
if (i==macroLoop) target+="| ";
|
||||
if (i==macroRel) target+="/ ";
|
||||
if (i==macroLen-1) {
|
||||
snprintf(buf,31,"%d",macro[i]);
|
||||
} else {
|
||||
|
@ -225,11 +234,12 @@ void FurnaceGUI::encodeMMLStr(String& target, unsigned char* macro, unsigned cha
|
|||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop) {
|
||||
void FurnaceGUI::encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel) {
|
||||
target="";
|
||||
char buf[32];
|
||||
for (int i=0; i<macroLen; i++) {
|
||||
if (i==macroLoop) target+="| ";
|
||||
if (i==macroRel) target+="/ ";
|
||||
if (i==macroLen-1) {
|
||||
snprintf(buf,31,"%d",macro[i]);
|
||||
} else {
|
||||
|
@ -283,7 +293,7 @@ void FurnaceGUI::decodeMMLStrW(String& source, int* macro, int& macroLen, int ma
|
|||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::decodeMMLStr(String& source, unsigned char* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax) {
|
||||
void FurnaceGUI::decodeMMLStr(String& source, unsigned char* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax, signed char& macroRel) {
|
||||
int buf=0;
|
||||
bool hasVal=false;
|
||||
macroLen=0;
|
||||
|
@ -311,6 +321,11 @@ void FurnaceGUI::decodeMMLStr(String& source, unsigned char* macro, unsigned cha
|
|||
macroLoop=macroLen;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (macroRel==-1) {
|
||||
macroRel=macroLen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (macroLen>=128) break;
|
||||
}
|
||||
|
@ -324,7 +339,7 @@ void FurnaceGUI::decodeMMLStr(String& source, unsigned char* macro, unsigned cha
|
|||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax) {
|
||||
void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax, signed char& macroRel) {
|
||||
int buf=0;
|
||||
bool negaBuf=false;
|
||||
bool hasVal=false;
|
||||
|
@ -360,6 +375,11 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
|||
macroLoop=macroLen;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (macroRel==-1) {
|
||||
macroRel=macroLen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (macroLen>=128) break;
|
||||
}
|
||||
|
@ -1381,7 +1401,7 @@ const int orderedOps[4]={
|
|||
|
||||
#define PARAMETER modified=true; e->notifyInsChange(curIns);
|
||||
|
||||
#define NORMAL_MACRO(macro,macroLen,macroLoop,macroMin,macroHeight,macroName,displayName,displayHeight,displayLoop,bitfield,bfVal,drawSlider,sliderVal,sliderLow,macroDispMin,bitOff,macroMode,macroColor,mmlStr,macroAMin,macroAMax) \
|
||||
#define NORMAL_MACRO(macro,macroLen,macroLoop,macroRel,macroMin,macroHeight,macroName,displayName,displayHeight,displayLoop,bitfield,bfVal,drawSlider,sliderVal,sliderLow,macroDispMin,bitOff,macroMode,macroColor,mmlStr,macroAMin,macroAMax) \
|
||||
ImGui::TableNextRow(); \
|
||||
ImGui::TableNextColumn(); \
|
||||
ImGui::Text("%s",displayName); \
|
||||
|
@ -1454,15 +1474,15 @@ const int orderedOps[4]={
|
|||
} \
|
||||
ImGui::SetNextItemWidth(availableWidth); \
|
||||
if (ImGui::InputText("##IMacroMML_" macroName,&mmlStr)) { \
|
||||
decodeMMLStr(mmlStr,macro,macroLen,macroLoop,macroAMin,(bitfield)?((1<<macroAMax)-1):macroAMax); \
|
||||
decodeMMLStr(mmlStr,macro,macroLen,macroLoop,macroAMin,(bitfield)?((1<<macroAMax)-1):macroAMax,macroRel); \
|
||||
} \
|
||||
if (!ImGui::IsItemActive()) { \
|
||||
encodeMMLStr(mmlStr,macro,macroLen,macroLoop); \
|
||||
encodeMMLStr(mmlStr,macro,macroLen,macroLoop,macroRel); \
|
||||
} \
|
||||
} \
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
#define OP_MACRO(macro,macroLen,macroLoop,macroHeight,op,macroName,displayName,displayHeight,displayLoop,bitfield,bfVal,mmlStr) \
|
||||
#define OP_MACRO(macro,macroLen,macroLoop,macroRel,macroHeight,op,macroName,displayName,displayHeight,displayLoop,bitfield,bfVal,mmlStr) \
|
||||
ImGui::TableNextRow(); \
|
||||
ImGui::TableNextColumn(); \
|
||||
ImGui::Text("%s",displayName); \
|
||||
|
@ -1524,10 +1544,10 @@ const int orderedOps[4]={
|
|||
} \
|
||||
ImGui::SetNextItemWidth(availableWidth); \
|
||||
if (ImGui::InputText("##IOPMacroMML_" macroName,&mmlStr)) { \
|
||||
decodeMMLStr(mmlStr,macro,macroLen,macroLoop,0,bitfield?((1<<macroHeight)-1):(macroHeight)); \
|
||||
decodeMMLStr(mmlStr,macro,macroLen,macroLoop,0,bitfield?((1<<macroHeight)-1):(macroHeight),macroRel); \
|
||||
} \
|
||||
if (!ImGui::IsItemActive()) { \
|
||||
encodeMMLStr(mmlStr,macro,macroLen,macroLoop); \
|
||||
encodeMMLStr(mmlStr,macro,macroLen,macroLoop,macroRel); \
|
||||
} \
|
||||
} \
|
||||
ImGui::PopStyleVar();
|
||||
|
@ -1651,15 +1671,15 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
if (ImGui::BeginTabItem("Macros (FM)")) {
|
||||
MACRO_BEGIN(0);
|
||||
NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,0,7,"alg",FM_NAME(FM_ALG),96,ins->std.algMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[0],0,7);
|
||||
NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,0,7,"fb",FM_NAME(FM_FB),96,ins->std.fbMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[1],0,7);
|
||||
NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,0,7,"fms",FM_NAME(FM_FMS),96,ins->std.fmsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,7);
|
||||
NORMAL_MACRO(ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop,0,3,"ams",FM_NAME(FM_AMS),48,ins->std.amsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[3],0,3);
|
||||
NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,ins->std.algMacroRel,0,7,"alg",FM_NAME(FM_ALG),96,ins->std.algMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[0],0,7);
|
||||
NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,ins->std.fbMacroRel,0,7,"fb",FM_NAME(FM_FB),96,ins->std.fbMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[1],0,7);
|
||||
NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,ins->std.fmsMacroRel,0,7,"fms",FM_NAME(FM_FMS),96,ins->std.fmsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,7);
|
||||
NORMAL_MACRO(ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop,ins->std.amsMacroRel,0,3,"ams",FM_NAME(FM_AMS),48,ins->std.amsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[3],0,3);
|
||||
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,0,127,"ex1","AM Depth",128,ins->std.ex1MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,127);
|
||||
NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,0,127,"ex2","PM Depth",128,ins->std.ex2MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,127);
|
||||
NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,0,255,"ex3","LFO Speed",128,ins->std.ex3MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,255);
|
||||
NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,0,3,"wave","LFO Shape",48,ins->std.waveMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[7],0,3);
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel,0,127,"ex1","AM Depth",128,ins->std.ex1MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,127);
|
||||
NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,ins->std.ex2MacroRel,0,127,"ex2","PM Depth",128,ins->std.ex2MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,127);
|
||||
NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,ins->std.ex3MacroRel,0,255,"ex3","LFO Speed",128,ins->std.ex3MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,255);
|
||||
NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel,0,3,"wave","LFO Shape",48,ins->std.waveMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[7],0,3);
|
||||
MACRO_END;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
@ -1669,18 +1689,18 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::PushID(i);
|
||||
MACRO_BEGIN(0);
|
||||
int ordi=orderedOps[i];
|
||||
OP_MACRO(ins->std.opMacros[ordi].tlMacro,ins->std.opMacros[ordi].tlMacroLen,ins->std.opMacros[ordi].tlMacroLoop,127,ordi,"tl",FM_NAME(FM_TL),128,ins->std.opMacros[ordi].tlMacroOpen,false,NULL,mmlString[0]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].arMacro,ins->std.opMacros[ordi].arMacroLen,ins->std.opMacros[ordi].arMacroLoop,31,ordi,"ar",FM_NAME(FM_AR),64,ins->std.opMacros[ordi].arMacroOpen,false,NULL,mmlString[1]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].drMacro,ins->std.opMacros[ordi].drMacroLen,ins->std.opMacros[ordi].drMacroLoop,31,ordi,"dr",FM_NAME(FM_DR),64,ins->std.opMacros[ordi].drMacroOpen,false,NULL,mmlString[2]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].d2rMacro,ins->std.opMacros[ordi].d2rMacroLen,ins->std.opMacros[ordi].d2rMacroLoop,31,ordi,"d2r",FM_NAME(FM_D2R),64,ins->std.opMacros[ordi].d2rMacroOpen,false,NULL,mmlString[3]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].rrMacro,ins->std.opMacros[ordi].rrMacroLen,ins->std.opMacros[ordi].rrMacroLoop,15,ordi,"rr",FM_NAME(FM_RR),64,ins->std.opMacros[ordi].rrMacroOpen,false,NULL,mmlString[4]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].slMacro,ins->std.opMacros[ordi].slMacroLen,ins->std.opMacros[ordi].slMacroLoop,15,ordi,"sl",FM_NAME(FM_SL),64,ins->std.opMacros[ordi].slMacroOpen,false,NULL,mmlString[5]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].rsMacro,ins->std.opMacros[ordi].rsMacroLen,ins->std.opMacros[ordi].rsMacroLoop,3,ordi,"rs",FM_NAME(FM_RS),32,ins->std.opMacros[ordi].rsMacroOpen,false,NULL,mmlString[6]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].multMacro,ins->std.opMacros[ordi].multMacroLen,ins->std.opMacros[ordi].multMacroLoop,15,ordi,"mult",FM_NAME(FM_MULT),64,ins->std.opMacros[ordi].multMacroOpen,false,NULL,mmlString[7]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].dtMacro,ins->std.opMacros[ordi].dtMacroLen,ins->std.opMacros[ordi].dtMacroLoop,7,ordi,"dt",FM_NAME(FM_DT),64,ins->std.opMacros[ordi].dtMacroOpen,false,NULL,mmlString[8]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].dt2Macro,ins->std.opMacros[ordi].dt2MacroLen,ins->std.opMacros[ordi].dt2MacroLoop,3,ordi,"dt2",FM_NAME(FM_DT2),32,ins->std.opMacros[ordi].dt2MacroOpen,false,NULL,mmlString[9]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].amMacro,ins->std.opMacros[ordi].amMacroLen,ins->std.opMacros[ordi].amMacroLoop,1,ordi,"am",FM_NAME(FM_AM),32,ins->std.opMacros[ordi].amMacroOpen,true,NULL,mmlString[10]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].ssgMacro,ins->std.opMacros[ordi].ssgMacroLen,ins->std.opMacros[ordi].ssgMacroLoop,4,ordi,"ssg",FM_NAME(FM_SSG),64,ins->std.opMacros[ordi].ssgMacroOpen,true,ssgEnvBits,mmlString[11]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].tlMacro,ins->std.opMacros[ordi].tlMacroLen,ins->std.opMacros[ordi].tlMacroLoop,ins->std.opMacros[ordi].tlMacroRel,127,ordi,"tl",FM_NAME(FM_TL),128,ins->std.opMacros[ordi].tlMacroOpen,false,NULL,mmlString[0]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].arMacro,ins->std.opMacros[ordi].arMacroLen,ins->std.opMacros[ordi].arMacroLoop,ins->std.opMacros[ordi].arMacroRel,31,ordi,"ar",FM_NAME(FM_AR),64,ins->std.opMacros[ordi].arMacroOpen,false,NULL,mmlString[1]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].drMacro,ins->std.opMacros[ordi].drMacroLen,ins->std.opMacros[ordi].drMacroLoop,ins->std.opMacros[ordi].drMacroRel,31,ordi,"dr",FM_NAME(FM_DR),64,ins->std.opMacros[ordi].drMacroOpen,false,NULL,mmlString[2]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].d2rMacro,ins->std.opMacros[ordi].d2rMacroLen,ins->std.opMacros[ordi].d2rMacroLoop,ins->std.opMacros[ordi].d2rMacroRel,31,ordi,"d2r",FM_NAME(FM_D2R),64,ins->std.opMacros[ordi].d2rMacroOpen,false,NULL,mmlString[3]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].rrMacro,ins->std.opMacros[ordi].rrMacroLen,ins->std.opMacros[ordi].rrMacroLoop,ins->std.opMacros[ordi].rrMacroRel,15,ordi,"rr",FM_NAME(FM_RR),64,ins->std.opMacros[ordi].rrMacroOpen,false,NULL,mmlString[4]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].slMacro,ins->std.opMacros[ordi].slMacroLen,ins->std.opMacros[ordi].slMacroLoop,ins->std.opMacros[ordi].slMacroRel,15,ordi,"sl",FM_NAME(FM_SL),64,ins->std.opMacros[ordi].slMacroOpen,false,NULL,mmlString[5]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].rsMacro,ins->std.opMacros[ordi].rsMacroLen,ins->std.opMacros[ordi].rsMacroLoop,ins->std.opMacros[ordi].rsMacroRel,3,ordi,"rs",FM_NAME(FM_RS),32,ins->std.opMacros[ordi].rsMacroOpen,false,NULL,mmlString[6]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].multMacro,ins->std.opMacros[ordi].multMacroLen,ins->std.opMacros[ordi].multMacroLoop,ins->std.opMacros[ordi].multMacroRel,15,ordi,"mult",FM_NAME(FM_MULT),64,ins->std.opMacros[ordi].multMacroOpen,false,NULL,mmlString[7]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].dtMacro,ins->std.opMacros[ordi].dtMacroLen,ins->std.opMacros[ordi].dtMacroLoop,ins->std.opMacros[ordi].dtMacroRel,7,ordi,"dt",FM_NAME(FM_DT),64,ins->std.opMacros[ordi].dtMacroOpen,false,NULL,mmlString[8]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].dt2Macro,ins->std.opMacros[ordi].dt2MacroLen,ins->std.opMacros[ordi].dt2MacroLoop,ins->std.opMacros[ordi].dt2MacroRel,3,ordi,"dt2",FM_NAME(FM_DT2),32,ins->std.opMacros[ordi].dt2MacroOpen,false,NULL,mmlString[9]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].amMacro,ins->std.opMacros[ordi].amMacroLen,ins->std.opMacros[ordi].amMacroLoop,ins->std.opMacros[ordi].amMacroRel,1,ordi,"am",FM_NAME(FM_AM),32,ins->std.opMacros[ordi].amMacroOpen,true,NULL,mmlString[10]);
|
||||
OP_MACRO(ins->std.opMacros[ordi].ssgMacro,ins->std.opMacros[ordi].ssgMacroLen,ins->std.opMacros[ordi].ssgMacroLoop,ins->std.opMacros[ordi].ssgMacroRel,4,ordi,"ssg",FM_NAME(FM_SSG),64,ins->std.opMacros[ordi].ssgMacroOpen,true,ssgEnvBits,mmlString[11]);
|
||||
MACRO_END;
|
||||
ImGui::PopID();
|
||||
ImGui::EndTabItem();
|
||||
|
@ -1881,41 +1901,41 @@ void FurnaceGUI::drawInsEdit() {
|
|||
|
||||
if (settings.macroView==0) { // modern view
|
||||
MACRO_BEGIN(28*dpiScale);
|
||||
NORMAL_MACRO(ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop,volMin,volMax,"vol",volumeLabel,160,ins->std.volMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_VOLUME],mmlString[0],volMin,volMax);
|
||||
NORMAL_MACRO(ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,arpMacroScroll,arpMacroScroll+24,"arp","Arpeggio",160,ins->std.arpMacroOpen,false,NULL,true,&arpMacroScroll,(arpMode?0:-80),0,0,&ins->std.arpMacroMode,uiColors[GUI_COLOR_MACRO_PITCH],mmlString[1],-92,94);
|
||||
NORMAL_MACRO(ins->std.volMacro,ins->std.volMacroLen,ins->std.volMacroLoop,ins->std.volMacroRel,volMin,volMax,"vol",volumeLabel,160,ins->std.volMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_VOLUME],mmlString[0],volMin,volMax);
|
||||
NORMAL_MACRO(ins->std.arpMacro,ins->std.arpMacroLen,ins->std.arpMacroLoop,ins->std.arpMacroRel,arpMacroScroll,arpMacroScroll+24,"arp","Arpeggio",160,ins->std.arpMacroOpen,false,NULL,true,&arpMacroScroll,(arpMode?0:-80),0,0,&ins->std.arpMacroMode,uiColors[GUI_COLOR_MACRO_PITCH],mmlString[1],-92,94);
|
||||
if (dutyMax>0) {
|
||||
NORMAL_MACRO(ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop,0,dutyMax,"duty",dutyLabel,160,ins->std.dutyMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,dutyMax);
|
||||
NORMAL_MACRO(ins->std.dutyMacro,ins->std.dutyMacroLen,ins->std.dutyMacroLoop,ins->std.dutyMacroRel,0,dutyMax,"duty",dutyLabel,160,ins->std.dutyMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,dutyMax);
|
||||
}
|
||||
if (waveMax>0) {
|
||||
NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,0,waveMax,"wave","Waveform",bitMode?64:160,ins->std.waveMacroOpen,bitMode,waveNames,false,NULL,0,0,((ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?1:0),NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[3],0,waveMax);
|
||||
NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel,0,waveMax,"wave","Waveform",bitMode?64:160,ins->std.waveMacroOpen,bitMode,waveNames,false,NULL,0,0,((ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?1:0),NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[3],0,waveMax);
|
||||
}
|
||||
if (ex1Max>0) {
|
||||
if (ins->type==DIV_INS_C64) {
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,0,ex1Max,"ex1","Filter Mode",64,ins->std.ex1MacroOpen,true,filtModeBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,ex1Max);
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel,0,ex1Max,"ex1","Filter Mode",64,ins->std.ex1MacroOpen,true,filtModeBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,ex1Max);
|
||||
} else if (ins->type==DIV_INS_SAA1099) {
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,0,ex1Max,"ex1","Envelope",160,ins->std.ex1MacroOpen,true,saaEnvBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,ex1Max);
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel,0,ex1Max,"ex1","Envelope",160,ins->std.ex1MacroOpen,true,saaEnvBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,ex1Max);
|
||||
} else {
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,0,ex1Max,"ex1","Duty",160,ins->std.ex1MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,ex1Max);
|
||||
NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel,0,ex1Max,"ex1","Duty",160,ins->std.ex1MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,ex1Max);
|
||||
}
|
||||
}
|
||||
if (ex2Max>0) {
|
||||
if (ins->type==DIV_INS_C64) {
|
||||
NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,0,ex2Max,"ex2","Resonance",64,ins->std.ex2MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,ex2Max);
|
||||
NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,ins->std.ex2MacroRel,0,ex2Max,"ex2","Resonance",64,ins->std.ex2MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,ex2Max);
|
||||
} else {
|
||||
NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,0,ex2Max,"ex2","Envelope",64,ins->std.ex2MacroOpen,true,ayEnvBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,ex2Max);
|
||||
NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,ins->std.ex2MacroRel,0,ex2Max,"ex2","Envelope",64,ins->std.ex2MacroOpen,true,ayEnvBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,ex2Max);
|
||||
}
|
||||
}
|
||||
if (ins->type==DIV_INS_C64) {
|
||||
NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,0,2,"ex3","Special",32,ins->std.ex3MacroOpen,true,c64SpecialBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,2);
|
||||
NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,ins->std.ex3MacroRel,0,2,"ex3","Special",32,ins->std.ex3MacroOpen,true,c64SpecialBits,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,2);
|
||||
}
|
||||
if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930) {
|
||||
NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,0,15,"ex3","AutoEnv Num",96,ins->std.ex3MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,15);
|
||||
NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,0,15,"alg","AutoEnv Den",96,ins->std.algMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[7],0,15);
|
||||
NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,ins->std.ex3MacroRel,0,15,"ex3","AutoEnv Num",96,ins->std.ex3MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,15);
|
||||
NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,ins->std.algMacroRel,0,15,"alg","AutoEnv Den",96,ins->std.algMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[7],0,15);
|
||||
}
|
||||
if (ins->type==DIV_INS_AY8930) {
|
||||
// oh my i am running out of macros
|
||||
NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,0,8,"fb","Noise AND Mask",96,ins->std.fbMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[8],0,8);
|
||||
NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,0,8,"fms","Noise OR Mask",96,ins->std.fmsMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[9],0,8);
|
||||
NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,ins->std.fbMacroRel,0,8,"fb","Noise AND Mask",96,ins->std.fbMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[8],0,8);
|
||||
NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,ins->std.fmsMacroRel,0,8,"fms","Noise OR Mask",96,ins->std.fmsMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[9],0,8);
|
||||
}
|
||||
|
||||
MACRO_END;
|
||||
|
@ -2295,7 +2315,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
decodeMMLStrW(mmlStringW,wave->data,wave->len,wave->max);
|
||||
}
|
||||
if (!ImGui::IsItemActive()) {
|
||||
encodeMMLStr(mmlStringW,wave->data,wave->len,-1);
|
||||
encodeMMLStr(mmlStringW,wave->data,wave->len,-1,-1);
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
|
||||
|
@ -4443,7 +4463,7 @@ void FurnaceGUI::doTranspose(int amount) {
|
|||
if (iFine==0) {
|
||||
int origNote=pat->data[j][0];
|
||||
int origOctave=(signed char)pat->data[j][1];
|
||||
if (origNote!=0 && origNote!=100) {
|
||||
if (origNote!=0 && origNote!=100 && origNote!=101 && origNote!=102) {
|
||||
origNote+=amount;
|
||||
while (origNote>12) {
|
||||
origNote-=12;
|
||||
|
@ -4759,6 +4779,8 @@ void FurnaceGUI::stopPreviewNote(SDL_Scancode scancode) {
|
|||
int num=12*curOctave+key;
|
||||
|
||||
if (key==100) return;
|
||||
if (key==101) return;
|
||||
if (key==102) return;
|
||||
|
||||
for (size_t i=0; i<activeNotes.size(); i++) {
|
||||
if (activeNotes[i].note==num) {
|
||||
|
@ -4974,6 +4996,12 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
if (key==100) { // note off
|
||||
pat->data[cursor.y][0]=100;
|
||||
pat->data[cursor.y][1]=0;
|
||||
} else if (key==101) { // note off + env release
|
||||
pat->data[cursor.y][0]=101;
|
||||
pat->data[cursor.y][1]=0;
|
||||
} else if (key==102) { // env release only
|
||||
pat->data[cursor.y][0]=102;
|
||||
pat->data[cursor.y][1]=0;
|
||||
} else {
|
||||
pat->data[cursor.y][0]=num%12;
|
||||
pat->data[cursor.y][1]=num/12;
|
||||
|
@ -4989,7 +5017,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
editAdvance();
|
||||
curNibble=false;
|
||||
} else {
|
||||
if (key!=100) {
|
||||
if (key!=100 && key!=101 && key!=102) {
|
||||
previewNote(cursor.xCoarse,num);
|
||||
}
|
||||
}
|
||||
|
@ -5052,7 +5080,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
try {
|
||||
int key=noteKeys.at(ev.key.keysym.scancode);
|
||||
int num=12*curOctave+key;
|
||||
if (key!=100) {
|
||||
if (key!=100 && key!=101 && key!=102) {
|
||||
previewNote(cursor.xCoarse,num);
|
||||
}
|
||||
} catch (std::out_of_range& e) {
|
||||
|
@ -5065,7 +5093,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
try {
|
||||
int key=noteKeys.at(ev.key.keysym.scancode);
|
||||
int num=12*curOctave+key;
|
||||
if (key!=100) {
|
||||
if (key!=100 && key!=101 && key!=102) {
|
||||
e->previewSample(curSample,num);
|
||||
samplePreviewOn=true;
|
||||
samplePreviewKey=ev.key.keysym.scancode;
|
||||
|
@ -5081,7 +5109,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
try {
|
||||
int key=noteKeys.at(ev.key.keysym.scancode);
|
||||
int num=12*curOctave+key;
|
||||
if (key!=100) {
|
||||
if (key!=100 && key!=101 && key!=102) {
|
||||
e->previewWave(curWave,num);
|
||||
wavePreviewOn=true;
|
||||
wavePreviewKey=ev.key.keysym.scancode;
|
||||
|
@ -6777,10 +6805,15 @@ FurnaceGUI::FurnaceGUI():
|
|||
noteKeys[SDL_SCANCODE_RIGHTBRACKET]=31;
|
||||
|
||||
// note off
|
||||
noteKeys[SDL_SCANCODE_EQUALS]=100;
|
||||
noteKeys[SDL_SCANCODE_TAB]=100;
|
||||
noteKeys[SDL_SCANCODE_1]=100;
|
||||
|
||||
// note off + env release
|
||||
noteKeys[SDL_SCANCODE_EQUALS]=101;
|
||||
|
||||
// env release
|
||||
noteKeys[SDL_SCANCODE_GRAVE]=102;
|
||||
|
||||
// value keys
|
||||
valueKeys[SDLK_0]=0;
|
||||
valueKeys[SDLK_1]=1;
|
||||
|
|
|
@ -401,10 +401,10 @@ class FurnaceGUI {
|
|||
|
||||
void applyUISettings();
|
||||
|
||||
void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop);
|
||||
void encodeMMLStr(String& target, unsigned char* macro, unsigned char macroLen, signed char macroLoop);
|
||||
void decodeMMLStr(String& source, unsigned char* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax);
|
||||
void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax);
|
||||
void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel);
|
||||
void encodeMMLStr(String& target, unsigned char* macro, unsigned char macroLen, signed char macroLoop, signed char macroRel);
|
||||
void decodeMMLStr(String& source, unsigned char* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax, signed char& macroRel);
|
||||
void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax, signed char& macroRel);
|
||||
void decodeMMLStrW(String& source, int* macro, int& macroLen, int macroMax);
|
||||
|
||||
const char* getSystemName(DivSystem which);
|
||||
|
|
Loading…
Reference in a new issue