dev111 - many macro changes

- max macro length is now 255
- loop/rel pos is now unsigned (255 = no)
- prepare for macro speed/delay
This commit is contained in:
tildearrow 2022-08-22 02:13:33 -05:00
parent 16309a8429
commit 2650fe609f
9 changed files with 333 additions and 55 deletions

View File

@ -32,6 +32,9 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
the format versions are: the format versions are:
- 111: Furnace dev111
- 110: Furnace dev110
- 109: Furnace dev109
- 108: Furnace dev108 - 108: Furnace dev108
- 107: Furnace dev107 - 107: Furnace dev107
- 106: Furnace dev106 - 106: Furnace dev106
@ -333,7 +336,8 @@ size | description
1 | E1xy and E2xy stop on same note (>=100) or reserved 1 | E1xy and E2xy stop on same note (>=100) or reserved
1 | broken initial position of porta after arp (>=101) or reserved 1 | broken initial position of porta after arp (>=101) or reserved
1 | SN periods under 8 are treated as 1 (>=108) or reserved 1 | SN periods under 8 are treated as 1 (>=108) or reserved
6 | reserved 1 | cut/delay effect policy (>=110) or reserved
5 | reserved
--- | **virtual tempo data** --- | **virtual tempo data**
2 | virtual tempo numerator of first song (>=96) or reserved 2 | virtual tempo numerator of first song (>=96) or reserved
2 | virtual tempo denominator of first song (>=96) or reserved 2 | virtual tempo denominator of first song (>=96) or reserved
@ -868,6 +872,96 @@ size | description
1 | K2 ramp 1 | K2 ramp
1 | K1 slow 1 | K1 slow
1 | K2 slow 1 | K2 slow
--- | **SNES data** (>=109)
1 | use envelope
1 | gain mode
1 | gain
1 | attack
1 | decay
1 | sustain
1 | release
--- | **macro speeds/delays** (>=111)
1 | volume macro speed
1 | arp macro speed
1 | duty macro speed
1 | wave macro speed
1 | pitch macro speed
1 | extra 1 macro speed
1 | extra 2 macro speed
1 | extra 3 macro speed
1 | alg macro speed
1 | fb macro speed
1 | fms macro speed
1 | ams macro speed
1 | left panning macro speed
1 | right panning macro speed
1 | phase reset macro speed
1 | extra 4 macro speed
1 | extra 5 macro speed
1 | extra 6 macro speed
1 | extra 7 macro speed
1 | extra 8 macro speed
1 | volume macro delay
1 | arp macro delay
1 | duty macro delay
1 | wave macro delay
1 | pitch macro delay
1 | extra 1 macro delay
1 | extra 2 macro delay
1 | extra 3 macro delay
1 | alg macro delay
1 | fb macro delay
1 | fms macro delay
1 | ams macro delay
1 | left panning macro delay
1 | right panning macro delay
1 | phase reset macro delay
1 | extra 4 macro delay
1 | extra 5 macro delay
1 | extra 6 macro delay
1 | extra 7 macro delay
1 | extra 8 macro delay
--- | **operator macro speeds/delay** × 4 (>=111)
1 | AM macro speed
1 | AR macro speed
1 | DR macro speed
1 | MULT macro speed
1 | RR macro speed
1 | SL macro speed
1 | TL macro speed
1 | DT2 macro speed
1 | RS macro speed
1 | DT macro speed
1 | D2R macro speed
1 | SSG-EG macro speed
1 | DAM macro speed
1 | DVB macro speed
1 | EGT macro speed
1 | KSL macro speed
1 | SUS macro speed
1 | VIB macro speed
1 | WS macro speed
1 | KSR macro speed
1 | AM macro delay
1 | AR macro delay
1 | DR macro delay
1 | MULT macro delay
1 | RR macro delay
1 | SL macro delay
1 | TL macro delay
1 | DT2 macro delay
1 | RS macro delay
1 | DT macro delay
1 | D2R macro delay
1 | SSG-EG macro delay
1 | DAM macro delay
1 | DVB macro delay
1 | EGT macro delay
1 | KSL macro delay
1 | SUS macro delay
1 | VIB macro delay
1 | WS macro delay
1 | KSR macro delay
``` ```
# wavetable # wavetable

View File

@ -46,8 +46,8 @@
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
#define BUSY_END isBusy.unlock(); softLocked=false; #define BUSY_END isBusy.unlock(); softLocked=false;
#define DIV_VERSION "dev110" #define DIV_VERSION "dev111"
#define DIV_ENGINE_VERSION 110 #define DIV_ENGINE_VERSION 111
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01

View File

@ -2843,9 +2843,9 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
// TODO: <= or <? // TODO: <= or <?
for (int k=0; k<=susTime; k++) { for (int k=0; k<=susTime; k++) {
ins->std.volMacro.val[ins->std.volMacro.len]=lastVal; ins->std.volMacro.val[ins->std.volMacro.len]=lastVal;
if (++ins->std.volMacro.len>=128) break; if (++ins->std.volMacro.len>=255) break;
} }
if (ins->std.volMacro.len>=128) break; if (ins->std.volMacro.len>=255) break;
} else if (m.val[j]==0xe9 || m.val[j]==0xea) { // volume slide } else if (m.val[j]==0xe9 || m.val[j]==0xea) { // volume slide
if (++j>=64) break; if (++j>=64) break;
signed char slideStep=m.val[j]; signed char slideStep=m.val[j];
@ -2864,16 +2864,16 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
} }
} }
ins->std.volMacro.val[ins->std.volMacro.len]=lastVal; ins->std.volMacro.val[ins->std.volMacro.len]=lastVal;
if (++ins->std.volMacro.len>=128) break; if (++ins->std.volMacro.len>=255) break;
} }
} else { } else {
// TODO: replace with upcoming macro speed // TODO: replace with upcoming macro speed
for (int k=0; k<MAX(1,seqSpeed); k++) { for (int k=0; k<MAX(1,seqSpeed); k++) {
ins->std.volMacro.val[ins->std.volMacro.len]=m.val[j]; ins->std.volMacro.val[ins->std.volMacro.len]=m.val[j];
lastVal=m.val[j]; lastVal=m.val[j];
if (++ins->std.volMacro.len>=128) break; if (++ins->std.volMacro.len>=255) break;
} }
if (ins->std.volMacro.len>=128) break; if (ins->std.volMacro.len>=255) break;
} }
} }
@ -2902,7 +2902,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
ins->std.waveMacro.val[ins->std.waveMacro.len]=wave-10; ins->std.waveMacro.val[ins->std.waveMacro.len]=wave-10;
ins->std.waveMacro.open=true; ins->std.waveMacro.open=true;
lastVal=wave; lastVal=wave;
//if (++ins->std.arpMacro.len>=128) break; //if (++ins->std.arpMacro.len>=255) break;
} }
} else if (fm.val[j]==0xe0) { } else if (fm.val[j]==0xe0) {
if (++j>=64) break; if (++j>=64) break;
@ -2932,8 +2932,8 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
ins->std.waveMacro.val[ins->std.waveMacro.len]=lastVal-10; ins->std.waveMacro.val[ins->std.waveMacro.len]=lastVal-10;
} }
ins->std.arpMacro.open=true; ins->std.arpMacro.open=true;
if (++ins->std.arpMacro.len>=128) break; if (++ins->std.arpMacro.len>=255) break;
if (++ins->std.waveMacro.len>=128) break; if (++ins->std.waveMacro.len>=255) break;
} }
} }
} }
@ -2946,7 +2946,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
// vibrato // vibrato
for (int j=0; j<=vibDelay; j++) { for (int j=0; j<=vibDelay; j++) {
ins->std.pitchMacro.val[ins->std.pitchMacro.len]=0; ins->std.pitchMacro.val[ins->std.pitchMacro.len]=0;
if (++ins->std.pitchMacro.len>=128) break; if (++ins->std.pitchMacro.len>=255) break;
} }
int vibPos=0; int vibPos=0;
ins->std.pitchMacro.loop=ins->std.pitchMacro.len; ins->std.pitchMacro.loop=ins->std.pitchMacro.len;
@ -2954,19 +2954,19 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
vibPos+=vibSpeed; vibPos+=vibSpeed;
if (vibPos>vibDepth) vibPos=vibDepth; if (vibPos>vibDepth) vibPos=vibDepth;
ins->std.pitchMacro.val[ins->std.pitchMacro.len]=vibPos*32; ins->std.pitchMacro.val[ins->std.pitchMacro.len]=vibPos*32;
if (++ins->std.pitchMacro.len>=128) break; if (++ins->std.pitchMacro.len>=255) break;
} while (vibPos<vibDepth); } while (vibPos<vibDepth);
do { do {
vibPos-=vibSpeed; vibPos-=vibSpeed;
if (vibPos<-vibDepth) vibPos=-vibDepth; if (vibPos<-vibDepth) vibPos=-vibDepth;
ins->std.pitchMacro.val[ins->std.pitchMacro.len]=vibPos*32; ins->std.pitchMacro.val[ins->std.pitchMacro.len]=vibPos*32;
if (++ins->std.pitchMacro.len>=128) break; if (++ins->std.pitchMacro.len>=255) break;
} while (vibPos>-vibDepth); } while (vibPos>-vibDepth);
do { do {
vibPos+=vibSpeed; vibPos+=vibSpeed;
if (vibPos>0) vibPos=0; if (vibPos>0) vibPos=0;
ins->std.pitchMacro.val[ins->std.pitchMacro.len]=vibPos*32; ins->std.pitchMacro.val[ins->std.pitchMacro.len]=vibPos*32;
if (++ins->std.pitchMacro.len>=128) break; if (++ins->std.pitchMacro.len>=255) break;
} while (vibPos<0); } while (vibPos<0);
ds.ins.push_back(ins); ds.ins.push_back(ins);

View File

@ -564,6 +564,96 @@ void DivInstrument::putInsData(SafeWriter* w) {
w->writeC(snes.s); w->writeC(snes.s);
w->writeC(snes.r); w->writeC(snes.r);
// macro speed/delay
w->writeC(std.volMacro.speed);
w->writeC(std.arpMacro.speed);
w->writeC(std.dutyMacro.speed);
w->writeC(std.waveMacro.speed);
w->writeC(std.pitchMacro.speed);
w->writeC(std.ex1Macro.speed);
w->writeC(std.ex2Macro.speed);
w->writeC(std.ex3Macro.speed);
w->writeC(std.algMacro.speed);
w->writeC(std.fbMacro.speed);
w->writeC(std.fmsMacro.speed);
w->writeC(std.amsMacro.speed);
w->writeC(std.panLMacro.speed);
w->writeC(std.panRMacro.speed);
w->writeC(std.phaseResetMacro.speed);
w->writeC(std.ex4Macro.speed);
w->writeC(std.ex5Macro.speed);
w->writeC(std.ex6Macro.speed);
w->writeC(std.ex7Macro.speed);
w->writeC(std.ex8Macro.speed);
w->writeC(std.volMacro.delay);
w->writeC(std.arpMacro.delay);
w->writeC(std.dutyMacro.delay);
w->writeC(std.waveMacro.delay);
w->writeC(std.pitchMacro.delay);
w->writeC(std.ex1Macro.delay);
w->writeC(std.ex2Macro.delay);
w->writeC(std.ex3Macro.delay);
w->writeC(std.algMacro.delay);
w->writeC(std.fbMacro.delay);
w->writeC(std.fmsMacro.delay);
w->writeC(std.amsMacro.delay);
w->writeC(std.panLMacro.delay);
w->writeC(std.panRMacro.delay);
w->writeC(std.phaseResetMacro.delay);
w->writeC(std.ex4Macro.delay);
w->writeC(std.ex5Macro.delay);
w->writeC(std.ex6Macro.delay);
w->writeC(std.ex7Macro.delay);
w->writeC(std.ex8Macro.delay);
// op macro speed/delay
for (int i=0; i<4; i++) {
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
w->writeC(op.amMacro.speed);
w->writeC(op.arMacro.speed);
w->writeC(op.drMacro.speed);
w->writeC(op.multMacro.speed);
w->writeC(op.rrMacro.speed);
w->writeC(op.slMacro.speed);
w->writeC(op.tlMacro.speed);
w->writeC(op.dt2Macro.speed);
w->writeC(op.rsMacro.speed);
w->writeC(op.dtMacro.speed);
w->writeC(op.d2rMacro.speed);
w->writeC(op.ssgMacro.speed);
w->writeC(op.damMacro.speed);
w->writeC(op.dvbMacro.speed);
w->writeC(op.egtMacro.speed);
w->writeC(op.kslMacro.speed);
w->writeC(op.susMacro.speed);
w->writeC(op.vibMacro.speed);
w->writeC(op.wsMacro.speed);
w->writeC(op.ksrMacro.speed);
w->writeC(op.amMacro.delay);
w->writeC(op.arMacro.delay);
w->writeC(op.drMacro.delay);
w->writeC(op.multMacro.delay);
w->writeC(op.rrMacro.delay);
w->writeC(op.slMacro.delay);
w->writeC(op.tlMacro.delay);
w->writeC(op.dt2Macro.delay);
w->writeC(op.rsMacro.delay);
w->writeC(op.dtMacro.delay);
w->writeC(op.d2rMacro.delay);
w->writeC(op.ssgMacro.delay);
w->writeC(op.damMacro.delay);
w->writeC(op.dvbMacro.delay);
w->writeC(op.egtMacro.delay);
w->writeC(op.kslMacro.delay);
w->writeC(op.susMacro.delay);
w->writeC(op.vibMacro.delay);
w->writeC(op.wsMacro.delay);
w->writeC(op.ksrMacro.delay);
}
blockEndSeek=w->tell(); blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET); w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4); w->writeI(blockEndSeek-blockStartSeek-4);
@ -960,15 +1050,15 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
// clear noise macro if PCE instrument and version<63 // clear noise macro if PCE instrument and version<63
if (version<63 && type==DIV_INS_PCE) { if (version<63 && type==DIV_INS_PCE) {
std.dutyMacro.len=0; std.dutyMacro.len=0;
std.dutyMacro.loop=-1; std.dutyMacro.loop=255;
std.dutyMacro.rel=-1; std.dutyMacro.rel=255;
} }
// clear wave macro if OPLL instrument and version<70 // clear wave macro if OPLL instrument and version<70
if (version<70 && type==DIV_INS_OPLL) { if (version<70 && type==DIV_INS_OPLL) {
std.waveMacro.len=0; std.waveMacro.len=0;
std.waveMacro.loop=-1; std.waveMacro.loop=255;
std.waveMacro.rel=-1; std.waveMacro.rel=255;
} }
// sample map // sample map
@ -1160,6 +1250,98 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
snes.r=reader.readC(); snes.r=reader.readC();
} }
// macro speed/delay
if (version>=111) {
std.volMacro.speed=reader.readC();
std.arpMacro.speed=reader.readC();
std.dutyMacro.speed=reader.readC();
std.waveMacro.speed=reader.readC();
std.pitchMacro.speed=reader.readC();
std.ex1Macro.speed=reader.readC();
std.ex2Macro.speed=reader.readC();
std.ex3Macro.speed=reader.readC();
std.algMacro.speed=reader.readC();
std.fbMacro.speed=reader.readC();
std.fmsMacro.speed=reader.readC();
std.amsMacro.speed=reader.readC();
std.panLMacro.speed=reader.readC();
std.panRMacro.speed=reader.readC();
std.phaseResetMacro.speed=reader.readC();
std.ex4Macro.speed=reader.readC();
std.ex5Macro.speed=reader.readC();
std.ex6Macro.speed=reader.readC();
std.ex7Macro.speed=reader.readC();
std.ex8Macro.speed=reader.readC();
std.volMacro.delay=reader.readC();
std.arpMacro.delay=reader.readC();
std.dutyMacro.delay=reader.readC();
std.waveMacro.delay=reader.readC();
std.pitchMacro.delay=reader.readC();
std.ex1Macro.delay=reader.readC();
std.ex2Macro.delay=reader.readC();
std.ex3Macro.delay=reader.readC();
std.algMacro.delay=reader.readC();
std.fbMacro.delay=reader.readC();
std.fmsMacro.delay=reader.readC();
std.amsMacro.delay=reader.readC();
std.panLMacro.delay=reader.readC();
std.panRMacro.delay=reader.readC();
std.phaseResetMacro.delay=reader.readC();
std.ex4Macro.delay=reader.readC();
std.ex5Macro.delay=reader.readC();
std.ex6Macro.delay=reader.readC();
std.ex7Macro.delay=reader.readC();
std.ex8Macro.delay=reader.readC();
// op macro speed/delay
for (int i=0; i<4; i++) {
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
op.amMacro.speed=reader.readC();
op.arMacro.speed=reader.readC();
op.drMacro.speed=reader.readC();
op.multMacro.speed=reader.readC();
op.rrMacro.speed=reader.readC();
op.slMacro.speed=reader.readC();
op.tlMacro.speed=reader.readC();
op.dt2Macro.speed=reader.readC();
op.rsMacro.speed=reader.readC();
op.dtMacro.speed=reader.readC();
op.d2rMacro.speed=reader.readC();
op.ssgMacro.speed=reader.readC();
op.damMacro.speed=reader.readC();
op.dvbMacro.speed=reader.readC();
op.egtMacro.speed=reader.readC();
op.kslMacro.speed=reader.readC();
op.susMacro.speed=reader.readC();
op.vibMacro.speed=reader.readC();
op.wsMacro.speed=reader.readC();
op.ksrMacro.speed=reader.readC();
op.amMacro.delay=reader.readC();
op.arMacro.delay=reader.readC();
op.drMacro.delay=reader.readC();
op.multMacro.delay=reader.readC();
op.rrMacro.delay=reader.readC();
op.slMacro.delay=reader.readC();
op.tlMacro.delay=reader.readC();
op.dt2Macro.delay=reader.readC();
op.rsMacro.delay=reader.readC();
op.dtMacro.delay=reader.readC();
op.d2rMacro.delay=reader.readC();
op.ssgMacro.delay=reader.readC();
op.damMacro.delay=reader.readC();
op.dvbMacro.delay=reader.readC();
op.egtMacro.delay=reader.readC();
op.kslMacro.delay=reader.readC();
op.susMacro.delay=reader.readC();
op.vibMacro.delay=reader.readC();
op.wsMacro.delay=reader.readC();
op.ksrMacro.delay=reader.readC();
}
}
return DIV_DATA_SUCCESS; return DIV_DATA_SUCCESS;
} }

View File

@ -165,21 +165,20 @@ struct DivInstrumentMacro {
int val[256]; int val[256];
unsigned int mode; unsigned int mode;
bool open; bool open;
unsigned char len; unsigned char len, delay, speed, loop, rel;
signed char loop;
signed char rel;
// the following variables are used by the GUI and not saved in the file // the following variables are used by the GUI and not saved in the file
int vScroll, vZoom; int vScroll, vZoom;
explicit DivInstrumentMacro(const String& n, bool initOpen=false): explicit DivInstrumentMacro(const String& n, bool initOpen=false):
name(n), name(n),
mode(0), mode(0),
open(initOpen), open(initOpen),
len(0), len(0),
loop(-1), delay(0),
rel(-1), speed(1),
loop(255),
rel(255),
vScroll(0), vScroll(0),
vZoom(-1) { vZoom(-1) {
memset(val,0,256*sizeof(int)); memset(val,0,256*sizeof(int));

View File

@ -43,15 +43,15 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic
if (has) { if (has) {
lastPos=pos; lastPos=pos;
val=source.val[pos++]; val=source.val[pos++];
if (source.rel>=0 && pos>source.rel && !released) { if (pos>source.rel && !released) {
if (source.loop<source.len && source.loop>=0 && source.loop<source.rel) { if (source.loop<source.len && source.loop<source.rel) {
pos=source.loop; pos=source.loop;
} else { } else {
pos--; pos--;
} }
} }
if (pos>=source.len) { if (pos>=source.len) {
if (source.loop<source.len && source.loop>=0 && (source.loop>=source.rel || source.rel>=source.len)) { if (source.loop<source.len && (source.loop>=source.rel || source.rel>=source.len)) {
pos=source.loop; pos=source.loop;
} else if (linger) { } else if (linger) {
pos--; pos--;
@ -240,7 +240,7 @@ void DivMacroInt::init(DivInstrument* which) {
for (size_t i=0; i<macroListLen; i++) { for (size_t i=0; i<macroListLen; i++) {
if (macroSource[i]!=NULL) { if (macroSource[i]!=NULL) {
macroList[i]->prepare(*macroSource[i],e); macroList[i]->prepare(*macroSource[i],e);
hasRelease=(macroSource[i]->rel>=0 && macroSource[i]->rel<macroSource[i]->len); hasRelease=(macroSource[i]->rel<macroSource[i]->len);
} else { } else {
hasRelease=false; hasRelease=false;
} }

View File

@ -276,13 +276,13 @@ void FurnaceGUI::decodeMMLStrW(String& source, int* macro, int& macroLen, int ma
} }
} }
void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax, signed char& macroRel) { void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLen, unsigned char& macroLoop, int macroMin, int macroMax, unsigned char& macroRel) {
int buf=0; int buf=0;
bool negaBuf=false; bool negaBuf=false;
bool hasVal=false; bool hasVal=false;
macroLen=0; macroLen=0;
macroLoop=-1; macroLoop=255;
macroRel=-1; macroRel=255;
for (char& i: source) { for (char& i: source) {
switch (i) { switch (i) {
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
@ -318,7 +318,7 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
macroLen++; macroLen++;
buf=0; buf=0;
} }
if (macroLoop==-1) { if (macroLoop==255) {
macroLoop=macroLen; macroLoop=macroLen;
} }
break; break;
@ -332,14 +332,14 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
macroLen++; macroLen++;
buf=0; buf=0;
} }
if (macroRel==-1) { if (macroRel==255) {
macroRel=macroLen; macroRel=macroLen;
} }
break; break;
} }
if (macroLen>=128) break; if (macroLen>=255) break;
} }
if (hasVal && macroLen<128) { if (hasVal && macroLen<255) {
hasVal=false; hasVal=false;
macro[macroLen]=negaBuf?-buf:buf; macro[macroLen]=negaBuf?-buf:buf;
negaBuf=false; negaBuf=false;

View File

@ -1406,7 +1406,7 @@ class FurnaceGUI {
ImVec2 macroLoopDragStart; ImVec2 macroLoopDragStart;
ImVec2 macroLoopDragAreaSize; ImVec2 macroLoopDragAreaSize;
signed char* macroLoopDragTarget; unsigned char* macroLoopDragTarget;
int macroLoopDragLen; int macroLoopDragLen;
bool macroLoopDragActive; bool macroLoopDragActive;
@ -1687,7 +1687,7 @@ class FurnaceGUI {
void initSystemPresets(); void initSystemPresets();
void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex=false); void encodeMMLStr(String& target, int* macro, int macroLen, int macroLoop, int macroRel, bool hex=false);
void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, signed char& macroLoop, int macroMin, int macroMax, signed char& macroRel); void decodeMMLStr(String& source, int* macro, unsigned char& macroLen, unsigned char& macroLoop, int macroMin, int macroMax, unsigned char& macroRel);
void decodeMMLStrW(String& source, int* macro, int& macroLen, int macroMax, bool hex=false); void decodeMMLStrW(String& source, int* macro, int& macroLen, int macroMax, bool hex=false);
String encodeKeyMap(std::map<int,int>& map); String encodeKeyMap(std::map<int,int>& map);

View File

@ -1215,14 +1215,14 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
} }
ImGui::TableNextColumn(); ImGui::TableNextColumn();
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace; float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
int totalFit=MIN(128,availableWidth/MAX(1,macroPointSize*dpiScale)); int totalFit=MIN(255,availableWidth/MAX(1,macroPointSize*dpiScale));
if (macroDragScroll>128-totalFit) { if (macroDragScroll>255-totalFit) {
macroDragScroll=128-totalFit; macroDragScroll=255-totalFit;
} }
ImGui::SetNextItemWidth(availableWidth); ImGui::SetNextItemWidth(availableWidth);
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,128-totalFit,"")) { if (CWSliderInt("##MacroScroll",&macroDragScroll,0,255-totalFit,"")) {
if (macroDragScroll<0) macroDragScroll=0; if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll>128-totalFit) macroDragScroll=128-totalFit; if (macroDragScroll>255-totalFit) macroDragScroll=255-totalFit;
} }
// draw macros // draw macros
@ -1239,8 +1239,11 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
} }
if (i.macro->open) { if (i.macro->open) {
ImGui::SetNextItemWidth(lenAvail); ImGui::SetNextItemWidth(lenAvail);
if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,&i.macro->len,&_ONE,&_THREE)) { MARK_MODIFIED int macroLen=i.macro->len;
if (i.macro->len>128) i.macro->len=128; if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,&macroLen,&_ONE,&_THREE)) { MARK_MODIFIED
if (macroLen<0) macroLen=0;
if (macroLen>255) macroLen=255;
i.macro->len=macroLen;
} }
// do not change this! // do not change this!
// anything other than a checkbox will look ugly! // anything other than a checkbox will look ugly!
@ -1267,7 +1270,7 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
if (j+macroDragScroll>=i.macro->len || (j+macroDragScroll>i.macro->rel && i.macro->loop<i.macro->rel)) { if (j+macroDragScroll>=i.macro->len || (j+macroDragScroll>i.macro->rel && i.macro->loop<i.macro->rel)) {
loopIndicator[j]=0; loopIndicator[j]=0;
} else { } else {
loopIndicator[j]=((i.macro->loop!=-1 && (j+macroDragScroll)>=i.macro->loop))|((i.macro->rel!=-1 && (j+macroDragScroll)==i.macro->rel)<<1); loopIndicator[j]=((i.macro->loop!=255 && (j+macroDragScroll)>=i.macro->loop))|((i.macro->rel!=255 && (j+macroDragScroll)==i.macro->rel)<<1);
} }
} }
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
@ -1414,9 +1417,9 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
} }
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
i.macro->rel=-1; i.macro->rel=255;
} else { } else {
i.macro->loop=-1; i.macro->loop=255;
} }
} }
ImGui::SetNextItemWidth(availableWidth); ImGui::SetNextItemWidth(availableWidth);
@ -1437,9 +1440,9 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::SetNextItemWidth(availableWidth); ImGui::SetNextItemWidth(availableWidth);
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,128-totalFit,"")) { if (CWSliderInt("##MacroScroll",&macroDragScroll,0,255-totalFit,"")) {
if (macroDragScroll<0) macroDragScroll=0; if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll>128-totalFit) macroDragScroll=128-totalFit; if (macroDragScroll>255-totalFit) macroDragScroll=255-totalFit;
} }
ImGui::EndTable(); ImGui::EndTable();
} }
@ -4311,8 +4314,8 @@ void FurnaceGUI::drawInsEdit() {
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("clear")) { if (ImGui::MenuItem("clear")) {
lastMacroDesc.macro->len=0; lastMacroDesc.macro->len=0;
lastMacroDesc.macro->loop=-1; lastMacroDesc.macro->loop=255;
lastMacroDesc.macro->rel=-1; lastMacroDesc.macro->rel=255;
for (int i=0; i<256; i++) { for (int i=0; i<256; i++) {
lastMacroDesc.macro->val[i]=0; lastMacroDesc.macro->val[i]=0;
} }
@ -4341,15 +4344,15 @@ void FurnaceGUI::drawInsEdit() {
lastMacroDesc.macro->val[i]=val; lastMacroDesc.macro->val[i]=val;
} }
if (lastMacroDesc.macro->loop>=0 && lastMacroDesc.macro->loop<lastMacroDesc.macro->len) { if (lastMacroDesc.macro->loop<lastMacroDesc.macro->len) {
lastMacroDesc.macro->loop+=macroOffX; lastMacroDesc.macro->loop+=macroOffX;
} else { } else {
lastMacroDesc.macro->loop=-1; lastMacroDesc.macro->loop=255;
} }
if ((lastMacroDesc.macro->rel+macroOffX)>=0 && (lastMacroDesc.macro->rel+macroOffX)<lastMacroDesc.macro->len) { if ((lastMacroDesc.macro->rel+macroOffX)>=0 && (lastMacroDesc.macro->rel+macroOffX)<lastMacroDesc.macro->len) {
lastMacroDesc.macro->rel+=macroOffX; lastMacroDesc.macro->rel+=macroOffX;
} else { } else {
lastMacroDesc.macro->rel=-1; lastMacroDesc.macro->rel=255;
} }
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();