several important bug fixes to advanced arp macro
This commit is contained in:
parent
c009cb3536
commit
226f43fea3
|
@ -1713,7 +1713,11 @@ int DivEngine::calcFreq(int base, int pitch, bool period, int octave, int pitch2
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::calcArp(int note, int arp, int offset) {
|
int DivEngine::calcArp(int note, int arp, int offset) {
|
||||||
|
if (arp<0) {
|
||||||
|
if (!(arp&0x40000000)) return (arp|0x40000000)+offset;
|
||||||
|
} else {
|
||||||
if (arp&0x40000000) return (arp&(~0x40000000))+offset;
|
if (arp&0x40000000) return (arp&(~0x40000000))+offset;
|
||||||
|
}
|
||||||
return note+arp;
|
return note+arp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -510,9 +510,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
ins->std.arpMacro.mode=0;
|
ins->std.arpMacro.mode=0;
|
||||||
for (int j=0; j<ins->std.arpMacro.len; j++) {
|
for (int j=0; j<ins->std.arpMacro.len; j++) {
|
||||||
ins->std.arpMacro.val[i]|=0x40000000;
|
ins->std.arpMacro.val[j]^=0x40000000;
|
||||||
}
|
}
|
||||||
if (ins->std.arpMacro.loop<ins->std.arpMacro.len && ins->std.arpMacro.len<255) {
|
if (ins->std.arpMacro.loop>=ins->std.arpMacro.len && ins->std.arpMacro.len<255) {
|
||||||
ins->std.arpMacro.val[ins->std.arpMacro.len++]=0;
|
ins->std.arpMacro.val[ins->std.arpMacro.len++]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2928,7 +2928,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
||||||
logV("unhandled pitch!");
|
logV("unhandled pitch!");
|
||||||
} else {
|
} else {
|
||||||
if (fm.val[j]>0x80) {
|
if (fm.val[j]>0x80) {
|
||||||
ins->std.arpMacro.val[ins->std.arpMacro.len]=(fm.val[j]-0x80+24)|0x40000000;
|
ins->std.arpMacro.val[ins->std.arpMacro.len]=(fm.val[j]-0x80+24)^0x40000000;
|
||||||
} else {
|
} else {
|
||||||
ins->std.arpMacro.val[ins->std.arpMacro.len]=fm.val[j];
|
ins->std.arpMacro.val[ins->std.arpMacro.len]=fm.val[j];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1347,9 +1347,9 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||||
if (std.arpMacro.mode) {
|
if (std.arpMacro.mode) {
|
||||||
std.arpMacro.mode=0;
|
std.arpMacro.mode=0;
|
||||||
for (int i=0; i<std.arpMacro.len; i++) {
|
for (int i=0; i<std.arpMacro.len; i++) {
|
||||||
std.arpMacro.val[i]|=0x40000000;
|
std.arpMacro.val[i]^=0x40000000;
|
||||||
}
|
}
|
||||||
if (std.arpMacro.loop<std.arpMacro.len && std.arpMacro.rel>std.arpMacro.loop && std.arpMacro.len<255) {
|
if ((std.arpMacro.loop>=std.arpMacro.len || std.arpMacro.rel>std.arpMacro.loop) && std.arpMacro.len<255) {
|
||||||
std.arpMacro.val[std.arpMacro.len++]=0;
|
std.arpMacro.val[std.arpMacro.len++]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,7 @@ void DivPlatformGB::tick(bool sysTick) {
|
||||||
if (chan[i].baseFreq>255) chan[i].baseFreq=255;
|
if (chan[i].baseFreq>255) chan[i].baseFreq=255;
|
||||||
if (chan[i].baseFreq<0) chan[i].baseFreq=0;
|
if (chan[i].baseFreq<0) chan[i].baseFreq=0;
|
||||||
} else {
|
} else {
|
||||||
chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val));
|
chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val,24));
|
||||||
}
|
}
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,9 @@ void DivPlatformTIA::tick(bool sysTick) {
|
||||||
// TODO: the way arps work on TIA is really weird
|
// TODO: the way arps work on TIA is really weird
|
||||||
if (chan[i].std.arp.had) {
|
if (chan[i].std.arp.had) {
|
||||||
if (!chan[i].inPorta) {
|
if (!chan[i].inPorta) {
|
||||||
if (chan[i].std.arp.val&0x40000000) {
|
if (chan[i].std.arp.val<0 && (!(chan[i].std.arp.val&0x40000000))) {
|
||||||
|
chan[i].baseFreq=0x80000000|(chan[i].std.arp.val|0x40000000);
|
||||||
|
} else if (chan[i].std.arp.val&0x40000000) {
|
||||||
chan[i].baseFreq=0x80000000|(chan[i].std.arp.val&(~0x40000000));
|
chan[i].baseFreq=0x80000000|(chan[i].std.arp.val&(~0x40000000));
|
||||||
} else {
|
} else {
|
||||||
chan[i].baseFreq=(chan[i].note+chan[i].std.arp.val)<<8;
|
chan[i].baseFreq=(chan[i].note+chan[i].std.arp.val)<<8;
|
||||||
|
|
|
@ -201,8 +201,13 @@ void FurnaceGUI::encodeMMLStr(String& target, int* macro, int macroLen, int macr
|
||||||
for (int i=0; i<macroLen; i++) {
|
for (int i=0; i<macroLen; i++) {
|
||||||
if (i==macroLoop) target+="| ";
|
if (i==macroLoop) target+="| ";
|
||||||
if (i==macroRel) target+="/ ";
|
if (i==macroRel) target+="/ ";
|
||||||
if (bit30 && macro[i]&0x40000000) target+="@";
|
if (bit30 && ((macro[i]&0xc0000000)==0x40000000 || (macro[i]&0xc0000000)==0x80000000)) target+="@";
|
||||||
int macroVal=macro[i]&(bit30?(~0x40000000):0xffffffff);
|
int macroVal=macro[i];
|
||||||
|
if (macro[i]<0) {
|
||||||
|
if (!(macroVal&0x40000000)) macroVal|=0x40000000;
|
||||||
|
} else {
|
||||||
|
if (macroVal&0x40000000) macroVal&=~0x40000000;
|
||||||
|
}
|
||||||
if (hex) {
|
if (hex) {
|
||||||
if (i==macroLen-1) {
|
if (i==macroLen-1) {
|
||||||
snprintf(buf,31,"%.2X",macroVal);
|
snprintf(buf,31,"%.2X",macroVal);
|
||||||
|
@ -312,7 +317,7 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
||||||
negaBuf=false;
|
negaBuf=false;
|
||||||
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
||||||
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
||||||
if (setBit30) macro[macroLen]|=0x40000000;
|
if (setBit30) macro[macroLen]^=0x40000000;
|
||||||
setBit30=false;
|
setBit30=false;
|
||||||
macroLen++;
|
macroLen++;
|
||||||
buf=0;
|
buf=0;
|
||||||
|
@ -325,7 +330,7 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
||||||
negaBuf=false;
|
negaBuf=false;
|
||||||
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
||||||
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
||||||
if (setBit30) macro[macroLen]|=0x40000000;
|
if (setBit30) macro[macroLen]^=0x40000000;
|
||||||
setBit30=false;
|
setBit30=false;
|
||||||
macroLen++;
|
macroLen++;
|
||||||
buf=0;
|
buf=0;
|
||||||
|
@ -341,7 +346,7 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
||||||
negaBuf=false;
|
negaBuf=false;
|
||||||
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
||||||
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
||||||
if (setBit30) macro[macroLen]|=0x40000000;
|
if (setBit30) macro[macroLen]^=0x40000000;
|
||||||
setBit30=false;
|
setBit30=false;
|
||||||
macroLen++;
|
macroLen++;
|
||||||
buf=0;
|
buf=0;
|
||||||
|
@ -359,7 +364,7 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
||||||
negaBuf=false;
|
negaBuf=false;
|
||||||
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
if (macro[macroLen]<macroMin) macro[macroLen]=macroMin;
|
||||||
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
if (macro[macroLen]>macroMax) macro[macroLen]=macroMax;
|
||||||
if (setBit30) macro[macroLen]|=0x40000000;
|
if (setBit30) macro[macroLen]^=0x40000000;
|
||||||
setBit30=false;
|
setBit30=false;
|
||||||
macroLen++;
|
macroLen++;
|
||||||
buf=0;
|
buf=0;
|
||||||
|
@ -1774,7 +1779,8 @@ void FurnaceGUI::showError(String what) {
|
||||||
displayError=true;
|
displayError=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define B30(tt) (macroDragBit30?((tt)&0x40000000):0)
|
// what monster did I just create here?
|
||||||
|
#define B30(tt) (macroDragBit30?((((tt)&0xc0000000)==0x40000000 || ((tt)&0xc0000000)==0x80000000)?0x40000000:0):0)
|
||||||
|
|
||||||
#define MACRO_DRAG(t) \
|
#define MACRO_DRAG(t) \
|
||||||
if (macroDragBitMode) { \
|
if (macroDragBitMode) { \
|
||||||
|
@ -1808,25 +1814,25 @@ void FurnaceGUI::showError(String what) {
|
||||||
} \
|
} \
|
||||||
if (macroDragMouseMoved) { \
|
if (macroDragMouseMoved) { \
|
||||||
if ((int)round(x-macroDragLineInitial.x)==0) { \
|
if ((int)round(x-macroDragLineInitial.x)==0) { \
|
||||||
t[x]=B30(t[x])|(int)(macroDragLineInitial.y); \
|
t[x]=B30(t[x])^(int)(macroDragLineInitial.y); \
|
||||||
} else { \
|
} else { \
|
||||||
if ((int)round(x-macroDragLineInitial.x)<0) { \
|
if ((int)round(x-macroDragLineInitial.x)<0) { \
|
||||||
for (int i=0; i<=(int)round(macroDragLineInitial.x-x); i++) { \
|
for (int i=0; i<=(int)round(macroDragLineInitial.x-x); i++) { \
|
||||||
int index=(int)round(x+i); \
|
int index=(int)round(x+i); \
|
||||||
if (index<0) continue; \
|
if (index<0) continue; \
|
||||||
t[index]=B30(t[index])|(int)(y+(macroDragLineInitial.y-y)*((float)i/(float)(macroDragLineInitial.x-x))); \
|
t[index]=B30(t[index])^(int)(y+(macroDragLineInitial.y-y)*((float)i/(float)(macroDragLineInitial.x-x))); \
|
||||||
} \
|
} \
|
||||||
} else { \
|
} else { \
|
||||||
for (int i=0; i<=(int)round(x-macroDragLineInitial.x); i++) { \
|
for (int i=0; i<=(int)round(x-macroDragLineInitial.x); i++) { \
|
||||||
int index=(int)round(i+macroDragLineInitial.x); \
|
int index=(int)round(i+macroDragLineInitial.x); \
|
||||||
if (index<0) continue; \
|
if (index<0) continue; \
|
||||||
t[index]=B30(t[index])|(int)(macroDragLineInitial.y+(y-macroDragLineInitial.y)*((float)i/(x-macroDragLineInitial.x))); \
|
t[index]=B30(t[index])^(int)(macroDragLineInitial.y+(y-macroDragLineInitial.y)*((float)i/(x-macroDragLineInitial.x))); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} else { \
|
} else { \
|
||||||
t[x]=B30(t[x])|(y); \
|
t[x]=B30(t[x])^(y); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1197,6 +1197,16 @@ String genericGuide(float value) {
|
||||||
return fmt::sprintf("%d",(int)value);
|
return fmt::sprintf("%d",(int)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int deBit30(const int val) {
|
||||||
|
if ((val&0xc0000000)==0x40000000 || (val&0xc0000000)==0x80000000) return val^0x40000000;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool enBit30(const int val) {
|
||||||
|
if ((val&0xc0000000)==0x40000000 || (val&0xc0000000)==0x80000000) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
float asFloat[256];
|
float asFloat[256];
|
||||||
int asInt[256];
|
int asInt[256];
|
||||||
|
@ -1292,9 +1302,9 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
asFloat[j]=0;
|
asFloat[j]=0;
|
||||||
asInt[j]=0;
|
asInt[j]=0;
|
||||||
} else {
|
} else {
|
||||||
asFloat[j]=i.macro->val[j+macroDragScroll]&(i.bit30?(~0x40000000):0xffffffff);
|
asFloat[j]=deBit30(i.macro->val[j+macroDragScroll]);
|
||||||
asInt[j]=(i.macro->val[j+macroDragScroll]&(i.bit30?(~0x40000000):0xffffffff))+i.bitOffset;
|
asInt[j]=deBit30(i.macro->val[j+macroDragScroll])+i.bitOffset;
|
||||||
if (i.bit30) bit30Indicator[j]=(i.macro->val[j+macroDragScroll]&0x40000000)?1:0;
|
if (i.bit30) bit30Indicator[j]=enBit30(i.macro->val[j+macroDragScroll]);
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
@ -1461,10 +1471,10 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
ImGui::SetNextItemWidth(availableWidth);
|
ImGui::SetNextItemWidth(availableWidth);
|
||||||
String& mmlStr=mmlString[index];
|
String& mmlStr=mmlString[index];
|
||||||
if (ImGui::InputText("##IMacroMML",&mmlStr)) {
|
if (ImGui::InputText("##IMacroMML",&mmlStr)) {
|
||||||
decodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.min,(i.isBitfield)?((1<<(i.isBitfield?i.max:0))-1):i.max,i.macro->rel);
|
decodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.min,(i.isBitfield)?((1<<(i.isBitfield?i.max:0))-1):i.max,i.macro->rel,i.bit30);
|
||||||
}
|
}
|
||||||
if (!ImGui::IsItemActive()) {
|
if (!ImGui::IsItemActive()) {
|
||||||
encodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.macro->rel);
|
encodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.macro->rel,false,i.bit30);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
Loading…
Reference in a new issue