dev182 - add a different macro release strat

active release makes the macro jump to release pos instead of waiting
This commit is contained in:
tildearrow 2023-10-11 03:36:21 -05:00
parent 8235f6ee66
commit 219665ed60
7 changed files with 46 additions and 9 deletions

View file

@ -84,6 +84,9 @@ each macro has two buttons on the left.
- **Step Length (ticks)**: determines how many ticks pass before each change of value. default is 1.
- **Delay**: delays the start of the macro until this many ticks have passed. default is 0.
- the button is highlighted if either of these is set differently from default.
- release mode. this determines how macro release is handled:
- **Active**: jumps to release position.
- **Passive**: does not jump to release position. if release position hasn't been reached yet, there will be a delay.
## macro types

View file

@ -251,6 +251,7 @@ size | description
| - 1: 8-bit signed
| - 2: 16-bit signed
| - 3: 32-bit signed
| - bit 3: instant release (>=182)
| - bit 1-2: type
| - 0: normal
| - 1: ADSR

View file

@ -52,10 +52,10 @@ class DivWorkPool;
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
//#define DIV_UNSTABLE
#define DIV_UNSTABLE
#define DIV_VERSION "0.6"
#define DIV_ENGINE_VERSION 181
#define DIV_VERSION "dev182"
#define DIV_ENGINE_VERSION 182
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02

View file

@ -319,7 +319,7 @@ void DivInstrument::writeMacro(SafeWriter* w, const DivInstrumentMacro& m) {
w->writeC(m.loop);
w->writeC(m.rel);
w->writeC(m.mode);
w->writeC(m.open|wordSize);
w->writeC((m.open&0x3f)|wordSize);
w->writeC(m.delay);
w->writeC(m.speed);
@ -2024,7 +2024,7 @@ void DivInstrument::readFeatureMA(SafeReader& reader, short version) {
target->mode=reader.readC();
unsigned char wordSize=reader.readC();
target->open=wordSize&7;
target->open=wordSize&15;
wordSize>>=6;
target->delay=reader.readC();

View file

@ -42,6 +42,7 @@ void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) {
has=had=actualHad=will=true;
mode=source.mode;
type=(source.open>>1)&3;
activeRelease=source.open&8;
linger=(source.macroType==DIV_MACRO_VOL && e->song.volMacroLinger);
lfoPos=LFO_PHASE;
}
@ -57,6 +58,10 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic
return;
}
if (released && type==1 && lastPos<3) delay=0;
if (released && type==0 && pos<source.rel && source.rel<source.len && activeRelease) {
delay=0;
pos=source.rel;
}
if (delay>0) {
delay--;
if (!linger) had=false;

View file

@ -27,7 +27,7 @@ class DivEngine;
struct DivMacroStruct {
int pos, lastPos, lfoPos, delay;
int val;
bool has, had, actualHad, finished, will, linger, began, masked;
bool has, had, actualHad, finished, will, linger, began, masked, activeRelease;
unsigned int mode, type;
unsigned char macroType;
void doMacro(DivInstrumentMacro& source, bool released, bool tick);
@ -54,6 +54,7 @@ struct DivMacroStruct {
linger(false),
began(true),
masked(false),
activeRelease(false),
mode(0),
type(0),
macroType(mType) {}

View file

@ -1749,9 +1749,10 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail
#define BUTTON_TO_SET_MODE(buttonType) \
if (buttonType(macroTypeLabels[(i.macro->open>>1)&3])) { \
unsigned char prevOpen=i.macro->open; \
i.macro->open+=2; \
if (i.macro->open>=6) { \
i.macro->open-=6; \
if (i.macro->open>=4) { \
i.macro->open&=(~6); \
} else { \
i.macro->open+=2; \
} \
\
/* check whether macro type is now ADSR/LFO or sequence */ \
@ -1819,6 +1820,20 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail
ImGui::EndPopup(); \
}
#define BUTTON_TO_SET_RELEASE(buttonType) \
pushToggleColors(i.macro->open&8); \
if (buttonType(ICON_FA_BOLT "##IMacroRelMode")) { \
i.macro->open^=8; \
} \
if (ImGui::IsItemHovered()) { \
if (i.macro->open&8) { \
ImGui::SetTooltip("Release mode: Active (jump to release pos)"); \
} else { \
ImGui::SetTooltip("Release mode: Passive (delayed release)"); \
} \
} \
popToggleColors(); \
void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUIMacroEditState& state) {
int index=0;
float reservedSpace=(settings.oldMacroVSlider)?(20.0f*dpiScale+ImGui::GetStyle().ItemSpacing.x):ImGui::GetStyle().ScrollbarSize;
@ -1881,6 +1896,10 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
BUTTON_TO_SET_MODE(ImGui::Button);
ImGui::SameLine();
BUTTON_TO_SET_PROPS(i);
if ((i.macro->open&6)==0) {
ImGui::SameLine();
BUTTON_TO_SET_RELEASE(ImGui::Button);
}
// do not change this!
// anything other than a checkbox will look ugly!
// if you really need more than two macro modes please tell me.
@ -1962,6 +1981,10 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
ImGui::SameLine();
}
BUTTON_TO_SET_PROPS(i);
if ((i.macro->open&6)==0) {
ImGui::SameLine();
BUTTON_TO_SET_RELEASE(ImGui::Button);
}
if (i.modeName!=NULL) {
bool modeVal=i.macro->mode;
String modeName=fmt::sprintf("%s##IMacroMode",i.modeName);
@ -2073,6 +2096,10 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
{
FurnaceGUIMacroDesc& i=m;
BUTTON_TO_SET_MODE(ImGui::Button);
if ((i.macro->open&6)==0) {
ImGui::SameLine();
BUTTON_TO_SET_RELEASE(ImGui::Button);
}
}
if (m.modeName!=NULL) {
bool modeVal=m.macro->mode;