diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index a6fedaa4..812428bf 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2593,8 +2593,7 @@ void FurnaceGUI::prepareUndo(ActionType action) { case GUI_UNDO_PATTERN_PASTE: case GUI_UNDO_PATTERN_CHANGE_INS: case GUI_UNDO_PATTERN_INTERPOLATE: - case GUI_UNDO_PATTERN_FADE_IN: - case GUI_UNDO_PATTERN_FADE_OUT: + case GUI_UNDO_PATTERN_FADE: case GUI_UNDO_PATTERN_SCALE: case GUI_UNDO_PATTERN_RANDOMIZE: case GUI_UNDO_PATTERN_INVERT_VAL: @@ -2644,8 +2643,7 @@ void FurnaceGUI::makeUndo(ActionType action) { case GUI_UNDO_PATTERN_PASTE: case GUI_UNDO_PATTERN_CHANGE_INS: case GUI_UNDO_PATTERN_INTERPOLATE: - case GUI_UNDO_PATTERN_FADE_IN: - case GUI_UNDO_PATTERN_FADE_OUT: + case GUI_UNDO_PATTERN_FADE: case GUI_UNDO_PATTERN_SCALE: case GUI_UNDO_PATTERN_RANDOMIZE: case GUI_UNDO_PATTERN_INVERT_VAL: @@ -3125,12 +3123,43 @@ void FurnaceGUI::doInterpolate() { makeUndo(GUI_UNDO_PATTERN_INTERPOLATE); } -// huh?! -void FurnaceGUI::doFade(bool fadeIn) { +void FurnaceGUI::doFade(int p0, int p1, bool mode) { finishSelection(); - prepareUndo(fadeIn?GUI_UNDO_PATTERN_FADE_IN:GUI_UNDO_PATTERN_FADE_OUT); + prepareUndo(GUI_UNDO_PATTERN_FADE); - makeUndo(fadeIn?GUI_UNDO_PATTERN_FADE_IN:GUI_UNDO_PATTERN_FADE_OUT); + int iCoarse=selStart.xCoarse; + int iFine=selStart.xFine; + int ord=e->getOrder(); + for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->song.chanShow[iCoarse]) continue; + DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); + for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.ins.empty()) continue; + absoluteTop=e->song.ins.size()-1; + } else if (iFine==2) { // volume + absoluteTop=e->getMaxVolumeChan(iCoarse); + } + if (selEnd.y-selStart.y<1) continue; + for (int j=selStart.y; j<=selEnd.y; j++) { + double fraction=double(j-selStart.y)/double(selEnd.y-selStart.y); + int value=p0+double(p1-p0)*fraction; + if (mode) { // nibble + value&=15; + pat->data[j][iFine+1]=MIN(absoluteTop,value|(value<<4)); + } else { // byte + pat->data[j][iFine+1]=MIN(absoluteTop,value); + } + } + } + } + iFine=0; + } + + makeUndo(GUI_UNDO_PATTERN_FADE); } void FurnaceGUI::doInvertValues() { @@ -3274,8 +3303,7 @@ void FurnaceGUI::doUndo() { case GUI_UNDO_PATTERN_PASTE: case GUI_UNDO_PATTERN_CHANGE_INS: case GUI_UNDO_PATTERN_INTERPOLATE: - case GUI_UNDO_PATTERN_FADE_IN: - case GUI_UNDO_PATTERN_FADE_OUT: + case GUI_UNDO_PATTERN_FADE: case GUI_UNDO_PATTERN_SCALE: case GUI_UNDO_PATTERN_RANDOMIZE: case GUI_UNDO_PATTERN_INVERT_VAL: @@ -3321,8 +3349,7 @@ void FurnaceGUI::doRedo() { case GUI_UNDO_PATTERN_PASTE: case GUI_UNDO_PATTERN_CHANGE_INS: case GUI_UNDO_PATTERN_INTERPOLATE: - case GUI_UNDO_PATTERN_FADE_IN: - case GUI_UNDO_PATTERN_FADE_OUT: + case GUI_UNDO_PATTERN_FADE: case GUI_UNDO_PATTERN_SCALE: case GUI_UNDO_PATTERN_RANDOMIZE: case GUI_UNDO_PATTERN_INVERT_VAL: @@ -3811,12 +3838,6 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_PAT_INTERPOLATE: doInterpolate(); break; - case GUI_ACTION_PAT_FADE_IN: - doFade(true); - break; - case GUI_ACTION_PAT_FADE_OUT: - doFade(false); - break; case GUI_ACTION_PAT_INVERT_VALUES: doInvertValues(); break; @@ -4745,6 +4766,7 @@ void FurnaceGUI::editOptions(bool topMenu) { ImGui::Separator(); ImGui::Text("operation mask"); + ImGui::SameLine(); ImGui::PushFont(patFont); if (ImGui::BeginTable("opMaskTable",5,ImGuiTableFlags_Borders|ImGuiTableFlags_SizingFixedFit|ImGuiTableFlags_NoHostExtendX)) { @@ -4803,8 +4825,6 @@ void FurnaceGUI::editOptions(bool topMenu) { ImGui::Separator(); if (ImGui::MenuItem("interpolate",BIND_FOR(GUI_ACTION_PAT_INTERPOLATE))) doInterpolate(); - if (ImGui::MenuItem("fade in",BIND_FOR(GUI_ACTION_PAT_FADE_IN))) doFade(true); - if (ImGui::MenuItem("fade out",BIND_FOR(GUI_ACTION_PAT_FADE_OUT))) doFade(false); if (ImGui::BeginMenu("change instrument...")) { if (e->song.ins.empty()) { ImGui::Text("no instruments available"); @@ -4817,6 +4837,38 @@ void FurnaceGUI::editOptions(bool topMenu) { } ImGui::EndMenu(); } + if (ImGui::BeginMenu("gradient/fade...")) { + if (ImGui::InputInt("Start",&fadeMin,1,1)) { + if (fadeMin<0) fadeMin=0; + if (fadeMode) { + if (fadeMin>15) fadeMin=15; + } else { + if (fadeMin>255) fadeMin=255; + } + } + if (ImGui::InputInt("End",&fadeMax,1,1)) { + if (fadeMax<0) fadeMax=0; + if (fadeMode) { + if (fadeMax>15) fadeMax=15; + } else { + if (fadeMax>255) fadeMax=255; + } + } + if (ImGui::Checkbox("Nibble mode",&fadeMode)) { + if (fadeMode) { + if (fadeMin>15) fadeMin=15; + if (fadeMax>15) fadeMax=15; + } else { + if (fadeMin>255) fadeMin=255; + if (fadeMax>255) fadeMax=255; + } + } + if (ImGui::Button("Go ahead")) { + doFade(fadeMin,fadeMax,fadeMode); + ImGui::CloseCurrentPopup(); + } + ImGui::EndMenu(); + } if (ImGui::BeginMenu("scale...")) { if (ImGui::InputFloat("##ScaleMax",&scaleMax,1,1,"%.1f%%")) { if (scaleMax<0.0f) scaleMax=0.0f; @@ -4839,6 +4891,7 @@ void FurnaceGUI::editOptions(bool topMenu) { if (randomizeMax255) randomizeMax=255; } + // TODO: add an option to set effect to specific value? if (ImGui::Button("Randomize")) { doRandomize(randomizeMin,randomizeMax); ImGui::CloseCurrentPopup(); @@ -6660,7 +6713,10 @@ FurnaceGUI::FurnaceGUI(): transposeAmount(0), randomizeMin(0), randomizeMax(255), + fadeMin(0), + fadeMax(255), scaleMax(100.0f), + fadeMode(false), oldOrdersLen(0) { // octave 1 diff --git a/src/gui/gui.h b/src/gui/gui.h index 65b3c34e..16312423 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -275,8 +275,7 @@ enum FurnaceGUIActions { GUI_ACTION_PAT_INCREASE_COLUMNS, GUI_ACTION_PAT_DECREASE_COLUMNS, GUI_ACTION_PAT_INTERPOLATE, - GUI_ACTION_PAT_FADE_IN, - GUI_ACTION_PAT_FADE_OUT, + GUI_ACTION_PAT_FADE, GUI_ACTION_PAT_INVERT_VALUES, GUI_ACTION_PAT_FLIP_SELECTION, GUI_ACTION_PAT_COLLAPSE_ROWS, @@ -383,8 +382,7 @@ enum ActionType { GUI_UNDO_PATTERN_PASTE, GUI_UNDO_PATTERN_CHANGE_INS, GUI_UNDO_PATTERN_INTERPOLATE, - GUI_UNDO_PATTERN_FADE_IN, - GUI_UNDO_PATTERN_FADE_OUT, + GUI_UNDO_PATTERN_FADE, GUI_UNDO_PATTERN_SCALE, GUI_UNDO_PATTERN_RANDOMIZE, GUI_UNDO_PATTERN_INVERT_VAL, @@ -691,8 +689,9 @@ class FurnaceGUI { ImVec2 threeChars, twoChars; SelectionPoint sel1, sel2; int dummyRows, demandX; - int transposeAmount, randomizeMin, randomizeMax; + int transposeAmount, randomizeMin, randomizeMax, fadeMin, fadeMax; float scaleMax; + bool fadeMode; int oldOrdersLen; DivOrders oldOrders; @@ -764,7 +763,7 @@ class FurnaceGUI { void doPaste(PasteMode mode=GUI_PASTE_MODE_NORMAL); void doChangeIns(int ins); void doInterpolate(); - void doFade(bool fadeIn); + void doFade(int p0, int p1, bool mode); void doInvertValues(); void doScale(float top); void doRandomize(int bottom, int top);