furnace/src/gui/insEdit.cpp

8981 lines
415 KiB
C++
Raw Normal View History

2022-02-17 13:08:17 -05:00
/**
* Furnace Tracker - multi-system chiptune tracker
2025-01-28 18:49:19 -05:00
* Copyright (C) 2021-2025 tildearrow and contributors
2022-02-17 13:08:17 -05:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
2022-12-14 23:38:38 -05:00
#define _USE_MATH_DEFINES
2022-02-17 13:08:17 -05:00
#include "gui.h"
2023-08-21 18:24:41 -04:00
#include "../ta-log.h"
2022-02-17 13:08:17 -05:00
#include "imgui_internal.h"
#include "../engine/macroInt.h"
// i don't know whether this is the right thing to do
#include "../engine/platform/sound/sid3.h"
2022-02-17 13:08:17 -05:00
#include "IconsFontAwesome4.h"
#include "furIcons.h"
2022-02-17 13:08:17 -05:00
#include "misc/cpp/imgui_stdlib.h"
#include "guiConst.h"
#include "intConst.h"
#include <fmt/printf.h>
2022-02-23 11:51:02 -05:00
#include <imgui.h>
2022-02-17 13:08:17 -05:00
#include "plot_nolerp.h"
#include "util.h"
2022-02-17 13:08:17 -05:00
2022-11-15 17:51:43 -05:00
extern "C" {
#include "../../extern/Nuked-OPLL/opll.h"
}
2022-02-17 13:08:17 -05:00
const char* ssgEnvTypes[8]={
2024-05-26 20:31:17 -04:00
_N("Down Down Down"),
_N("Down."),
_N("Down Up Down Up"),
_N("Down UP"),
_N("Up Up Up"),
_N("Up."),
_N("Up Down Up Down"),
_N("Up DOWN")
2022-02-17 13:08:17 -05:00
};
const char* fmParamNames[3][33]={
2025-01-28 03:52:17 -05:00
{_N("Algorithm"), _N("Feedback"), _N("LFO > Freq"), _N("LFO > Amp"), _N("Attack"), _N("Decay"), _N("Decay 2"), _N("Release"), _N("Sustain"), _N("Level"), _N("EnvScale"), _N("Multiplier"), _N("Detune"), _N("Detune 2"), _N("SSG-EG"), _N("AM"), _N("AM Depth"), _N("Vibrato Depth"), _N("Sustained"), _N("Sustained"), _N("Level Scaling"), _N("Sustain"), _N("Vibrato"), _N("Waveform"), _N("Scale Rate"), _N("OP2 Half Sine"), _N("OP1 Half Sine"), _N("EnvShift"), _N("Reverb"), _N("Fine"), _N("LFO2 > Freq"), _N("LFO2 > Amp"), _N("Octave")},
{"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "SR", "RR", "SL", "TL", "KS", "MULT", "DT", "DT2", "SSG-EG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2", "Block"},
{"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2", "Block"}
2022-02-17 13:08:17 -05:00
};
const char* esfmParamLongNames[9]={
2024-05-26 20:31:17 -04:00
_N("OP4 Noise Mode"),
_N("Envelope Delay"),
_N("Output Level"),
_N("Modulation Input Level"),
_N("Left Output"),
_N("Right Output"),
_N("Coarse Tune (semitones)"),
_N("Detune"),
_N("Fixed Frequency Mode")
};
const char* esfmParamNames[9]={
2024-05-26 20:31:17 -04:00
_N("OP4 Noise Mode"),
_N("Env. Delay"),
_N("Output Level"),
_N("ModInput"),
_N("Left"),
_N("Right"),
_N("Tune"),
_N("Detune"),
_N("Fixed")
};
const char* esfmParamShortNames[9]={
2023-10-26 08:45:46 -04:00
"NOI", "DL", "OL", "MI", "L", "R", "CT", "DT", "FIX"
};
const char* fmParamShortNames[3][32]={
{"ALG", "FB", "FMS", "AMS", "A", "D", "D2", "R", "S", "TL", "RS", "ML", "DT", "DT2", "SSG", "AM", "DAM", "DVB", "SUS", "SUS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS2", "AMS2"},
{"ALG", "FB", "FMS", "AMS", "A", "D", "SR", "R", "S", "TL", "KS", "ML", "DT", "DT2", "SSG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS2", "AMS2"},
{"ALG", "FB", "FMS", "AMS", "A", "D", "D2", "R", "S", "TL", "RS", "ML", "DT", "DT2", "SSG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS2", "AMS2"}
2022-03-27 04:29:45 -04:00
};
2022-08-03 00:16:42 -04:00
const char* opllVariants[4]={
"OPLL",
"YMF281",
"YM2423",
"VRC7"
};
const char* opllInsNames[4][17]={
/* YM2413 */ {
2024-05-26 20:31:17 -04:00
_N("User"),
_N("1. Violin"),
_N("2. Guitar"),
_N("3. Piano"),
_N("4. Flute"),
_N("5. Clarinet"),
_N("6. Oboe"),
_N("7. Trumpet"),
_N("8. Organ"),
_N("9. Horn"),
_N("10. Synth"),
_N("11. Harpsichord"),
_N("12. Vibraphone"),
_N("13. Synth Bass"),
_N("14. Acoustic Bass"),
_N("15. Electric Guitar"),
_N("Drums")
2022-08-03 00:16:42 -04:00
},
/* YMF281 */ {
2024-05-26 20:31:17 -04:00
_N("User"),
_N("1. Electric String"),
_N("2. Bow wow"),
_N("3. Electric Guitar"),
_N("4. Organ"),
_N("5. Clarinet"),
_N("6. Saxophone"),
_N("7. Trumpet"),
_N("8. Street Organ"),
_N("9. Synth Brass"),
_N("10. Electric Piano"),
_N("11. Bass"),
_N("12. Vibraphone"),
_N("13. Chime"),
_N("14. Tom Tom II"),
_N("15. Noise"),
_N("Drums")
2022-08-03 00:16:42 -04:00
},
/* YM2423 */ {
2024-05-26 20:31:17 -04:00
_N("User"),
_N("1. Strings"),
_N("2. Guitar"),
_N("3. Electric Guitar"),
_N("4. Electric Piano"),
_N("5. Flute"),
_N("6. Marimba"),
_N("7. Trumpet"),
_N("8. Harmonica"),
_N("9. Tuba"),
_N("10. Synth Brass"),
_N("11. Short Saw"),
_N("12. Vibraphone"),
_N("13. Electric Guitar 2"),
_N("14. Synth Bass"),
_N("15. Sitar"),
_N("Drums")
2022-08-03 00:16:42 -04:00
},
// stolen from FamiTracker
/* VRC7 */ {
2024-05-26 20:31:17 -04:00
_N("User"),
_N("1. Bell"),
_N("2. Guitar"),
_N("3. Piano"),
_N("4. Flute"),
_N("5. Clarinet"),
_N("6. Rattling Bell"),
_N("7. Trumpet"),
_N("8. Reed Organ"),
_N("9. Soft Bell"),
_N("10. Xylophone"),
_N("11. Vibraphone"),
_N("12. Brass"),
_N("13. Bass Guitar"),
_N("14. Synth"),
_N("15. Chorus"),
_N("Drums")
2022-08-03 00:16:42 -04:00
}
};
2022-03-08 13:12:20 -05:00
const char* oplWaveforms[8]={
2024-05-26 20:31:17 -04:00
_N("Sine"),
_N("Half Sine"),
_N("Absolute Sine"),
_N("Quarter Sine"),
_N("Squished Sine"),
_N("Squished AbsSine"),
_N("Square"),
_N("Derived Square")
2022-03-08 13:12:20 -05:00
};
const char* oplWaveformsStandard[8]={
2024-05-26 20:31:17 -04:00
_N("Sine"),
_N("Half Sine"),
_N("Absolute Sine"),
_N("Pulse Sine"),
_N("Sine (Even Periods)"),
_N("AbsSine (Even Periods)"),
_N("Square"),
_N("Derived Square")
};
2022-03-08 13:46:48 -05:00
const char* opzWaveforms[8]={
2024-05-26 20:31:17 -04:00
_N("Sine"),
_N("Triangle"),
_N("Cut Sine"),
_N("Cut Triangle"),
_N("Squished Sine"),
_N("Squished Triangle"),
_N("Squished AbsSine"),
_N("Squished AbsTriangle")
2022-03-08 13:46:48 -05:00
};
const char* oplDrumNames[4]={
2024-05-26 20:31:17 -04:00
_N("Snare"),
_N("Tom"),
_N("Top"),
_N("HiHat")
};
const char* esfmNoiseModeNames[4]={
2024-05-26 20:31:17 -04:00
_N("Normal"),
_N("Snare"),
_N("HiHat"),
_N("Top")
};
const char* esfmNoiseModeDescriptions[4]={
2024-05-26 20:31:17 -04:00
_N("Noise disabled"),
_N("Square + noise"),
_N("Ringmod from OP3 + noise"),
_N("Ringmod from OP3 + double pitch ModInput\nWARNING - has emulation issues; subject to change")
};
2024-04-21 13:59:19 -04:00
const char* sid2WaveMixModes[5]={
_N("8580 SID"),
2024-05-26 20:31:17 -04:00
_N("Bitwise AND"),
_N("Bitwise OR"),
_N("Bitwise XOR"),
NULL
2024-04-21 13:59:19 -04:00
};
2024-04-21 14:03:03 -04:00
const char* sid2ControlBits[4]={
2024-05-26 20:31:17 -04:00
_N("gate"),
_N("sync"),
_N("ring"),
NULL
2024-04-21 14:03:03 -04:00
};
const char* sid3ControlBits[4]={
_N("phase"),
_N("sync"),
_N("ring"),
NULL
};
const char* sid3WaveMixModes[6]={
_N("8580 SID"),
_N("Bitwise AND"),
_N("Bitwise OR"),
_N("Bitwise XOR"),
_N("Sum of the signals"),
NULL
};
const char* sid3SpecialWaveforms[]={
_N("Sine"),
_N("Rect. Sine"),
_N("Abs. Sine"),
_N("Quart. Sine"),
_N("Squish. Sine"),
_N("Abs. Squish. Sine"),
_N("Rect. Saw"),
_N("Abs. Saw"),
_N("Cubed Saw"),
_N("Rect. Cubed Saw"),
_N("Abs. Cubed Saw"),
_N("Cubed Sine"),
_N("Rect. Cubed Sine"),
_N("Abs. Cubed Sine"),
_N("Quart. Cubed Sine"),
_N("Squish. Cubed Sine"),
_N("Squish. Abs. Cub. Sine"),
_N("Rect. Triangle"),
_N("Abs. Triangle"),
_N("Quart. Triangle"),
_N("Squish. Triangle"),
_N("Abs. Squish. Triangle"),
_N("Cubed Triangle"),
_N("Rect. Cubed Triangle"),
_N("Abs. Cubed Triangle"),
_N("Quart. Cubed Triangle"),
_N("Squish. Cubed Triangle"),
_N("Squish. Abs. Cub. Triangle"),
// clipped
_N("Clipped Sine"),
_N("Clipped Rect. Sine"),
_N("Clipped Abs. Sine"),
_N("Clipped Quart. Sine"),
_N("Clipped Squish. Sine"),
_N("Clipped Abs. Squish. Sine"),
_N("Clipped Rect. Saw"),
_N("Clipped Abs. Saw"),
_N("Clipped Cubed Saw"),
_N("Clipped Rect. Cubed Saw"),
_N("Clipped Abs. Cubed Saw"),
_N("Clipped Cubed Sine"),
_N("Clipped Rect. Cubed Sine"),
_N("Clipped Abs. Cubed Sine"),
_N("Clipped Quart. Cubed Sine"),
_N("Clipped Squish. Cubed Sine"),
_N("Clipped Squish. Abs. Cub. Sine"),
_N("Clipped Rect. Triangle"),
_N("Clipped Abs. Triangle"),
_N("Clipped Quart. Triangle"),
_N("Clipped Squish. Triangle"),
_N("Clipped Abs. Squish. Triangle"),
_N("Clipped Cubed Triangle"),
_N("Clipped Rect. Cubed Triangle"),
_N("Clipped Abs. Cubed Triangle"),
_N("Clipped Quart. Cubed Triangle"),
_N("Clipped Squish. Cubed Triangle"),
_N("Clipped Squish. Abs. Cub. Triangle"),
// two clipped simple waves
_N("Clipped Triangle"),
_N("Clipped Saw")
};
const bool opIsOutput[8][4]={
{false,false,false,true},
{false,false,false,true},
{false,false,false,true},
{false,false,false,true},
{false,true,false,true},
{false,true,true,true},
{false,true,true,true},
{true,true,true,true}
};
const bool opIsOutputOPL[4][4]={
{false,false,false,true},
{true,false,false,true},
{false,true,false,true},
{true,false,true,true}
};
2022-02-17 13:08:17 -05:00
enum FMParams {
FM_ALG=0,
FM_FB=1,
FM_FMS=2,
FM_AMS=3,
FM_AR=4,
FM_DR=5,
FM_D2R=6,
FM_RR=7,
FM_SL=8,
FM_TL=9,
FM_RS=10,
FM_MULT=11,
FM_DT=12,
FM_DT2=13,
FM_SSG=14,
FM_AM=15,
FM_DAM=16,
FM_DVB=17,
FM_EGT=18,
FM_EGS=19,
FM_KSL=20,
FM_SUS=21,
FM_VIB=22,
FM_WS=23,
FM_KSR=24,
FM_DC=25,
FM_DM=26,
FM_EGSHIFT=27,
FM_REV=28,
FM_FINE=29,
FM_FMS2=30,
FM_AMS2=31,
FM_BLOCK=32
2022-02-17 13:08:17 -05:00
};
enum ESFMParams {
ESFM_NOISE=0,
ESFM_DELAY=1,
ESFM_OUTLVL=2,
ESFM_MODIN=3,
ESFM_LEFT=4,
ESFM_RIGHT=5,
ESFM_CT=6,
ESFM_DT=7,
ESFM_FIXED=8
};
2024-05-26 20:31:17 -04:00
#define FM_NAME(x) _(fmParamNames[settings.fmNames][x])
2022-03-27 04:29:45 -04:00
#define FM_SHORT_NAME(x) fmParamShortNames[settings.fmNames][x]
2024-05-26 20:31:17 -04:00
#define ESFM_LONG_NAME(x) _(esfmParamLongNames[x])
#define ESFM_NAME(x) _(esfmParamNames[x])
#define ESFM_SHORT_NAME(x) (esfmParamShortNames[x])
2022-02-17 13:08:17 -05:00
2022-10-07 05:11:45 -04:00
const char* macroTypeLabels[4]={
ICON_FA_BAR_CHART "##IMacroType",
ICON_FUR_ADSR "##IMacroType",
ICON_FUR_TRI "##IMacroType",
2022-10-07 05:11:45 -04:00
ICON_FA_SIGN_OUT "##IMacroType"
};
2022-10-07 17:47:18 -04:00
const char* macroLFOShapes[4]={
2024-05-26 20:31:17 -04:00
_N("Triangle"),
_N("Saw"),
_N("Square"),
_N("How did you even")
2022-10-07 17:47:18 -04:00
};
const char* fmOperatorBits[5]={
2022-04-10 17:52:03 -04:00
"op1", "op2", "op3", "op4", NULL
};
2022-02-17 13:08:17 -05:00
const char* c64ShapeBits[5]={
2024-05-26 20:31:17 -04:00
_N("triangle"),
_N("saw"),
_N("pulse"),
_N("noise"),
NULL
2022-02-17 13:08:17 -05:00
};
const char* ayShapeBits[4]={
2024-05-26 20:31:17 -04:00
_N("tone"),
_N("noise"),
_N("envelope"),
NULL
2022-02-17 13:08:17 -05:00
};
const char* sid3ShapeBits[6]={
_N("triangle"),
_N("saw"),
_N("pulse"),
_N("noise"),
_N("special wave"),
NULL
};
const char* sid3FilterMatrixBits[5]={
_N("From filter 1"),
_N("From filter 2"),
_N("From filter 3"),
_N("From filter 4"),
NULL
};
2022-02-17 13:08:17 -05:00
const char* ayEnvBits[4]={
2024-05-26 20:31:17 -04:00
_N("hold"),
_N("alternate"),
_N("direction"),
_N("enable")
2022-02-17 13:08:17 -05:00
};
const char* ssgEnvBits[5]={
2024-05-26 20:31:17 -04:00
"0", "1", "2", _N("enabled"), NULL
2022-02-17 13:08:17 -05:00
};
const char* saaEnvBits[9]={
2024-05-26 20:31:17 -04:00
_N("mirror"),
_N("loop"),
_N("cut"),
_N("direction"),
_N("resolution"),
_N("fixed"),
_N("N/A"),
_N("enabled"),
NULL
2022-02-17 13:08:17 -05:00
};
const char* snesModeBits[6]={
2024-05-26 20:31:17 -04:00
_N("noise"),
_N("echo"),
_N("pitch mod"),
_N("invert right"),
_N("invert left"),
NULL
};
2022-02-17 13:08:17 -05:00
const char* filtModeBits[5]={
2024-05-26 20:31:17 -04:00
_N("low"),
_N("band"),
_N("high"),
_N("ch3off"),
NULL
2022-02-17 13:08:17 -05:00
};
const char* c64TestGateBits[5]={
2024-05-26 20:31:17 -04:00
_N("gate"),
_N("sync"),
_N("ring"),
_N("test"),
NULL
2022-02-17 13:08:17 -05:00
};
2022-12-20 02:59:26 -05:00
const char* pokeyCtlBits[9]={
2024-05-26 20:31:17 -04:00
_N("15KHz"),
_N("filter 2+4"),
_N("filter 1+3"),
_N("16-bit 3+4"),
_N("16-bit 1+2"),
_N("high3"),
_N("high1"),
_N("poly9"),
NULL
2022-12-20 02:59:26 -05:00
};
const char* mikeyFeedbackBits[11]={
2022-02-20 12:15:15 -05:00
"0", "1", "2", "3", "4", "5", "7", "10", "11", "int", NULL
};
2022-10-01 20:47:40 -04:00
const char* msm5232ControlBits[7]={
2024-05-26 20:31:17 -04:00
_N("16'"),
_N("8'"),
_N("4'"),
_N("2'"),
_N("sustain"),
NULL
2022-10-01 04:15:40 -04:00
};
2023-07-23 05:42:38 -04:00
const char* tedControlBits[3]={
2024-05-26 20:31:17 -04:00
_N("square"),
_N("noise"),
NULL
2023-07-23 05:42:38 -04:00
};
const char* c219ControlBits[4]={
2024-05-26 20:31:17 -04:00
_N("noise"),
_N("invert"),
_N("surround"),
NULL
};
const char* x1_010EnvBits[8]={
2024-05-26 20:31:17 -04:00
_N("enable"),
_N("oneshot"),
_N("split L/R"),
_N("HinvR"),
_N("VinvR"),
_N("HinvL"),
_N("VinvL"),
NULL
};
const char* suControlBits[5]={
2024-05-26 20:31:17 -04:00
_N("ring mod"),
_N("low pass"),
_N("high pass"),
_N("band pass"),
NULL
};
const char* es5506FilterModes[4]={
"HP/K2, HP/K2", "HP/K2, LP/K1", "LP/K2, LP/K2", "LP/K2, LP/K1",
};
2024-01-24 13:14:49 -05:00
const char* powerNoiseControlBits[3]={
2024-05-26 20:31:17 -04:00
_N("enable tap B"),
_N("AM with slope"),
NULL
};
const char* powerNoiseSlopeControlBits[7]={
2024-05-26 20:31:17 -04:00
_N("invert B"),
_N("invert A"),
_N("reset B"),
_N("reset A"),
_N("clip B"),
_N("clip A"),
NULL
};
2024-02-04 02:05:00 -05:00
const char* daveControlBits[5]={
2024-05-26 20:31:17 -04:00
_N("high pass"),
_N("ring mod"),
_N("swap counters (noise)"),
_N("low pass (noise)"),
NULL
2024-02-04 02:05:00 -05:00
};
2023-01-04 19:16:37 -05:00
const char* panBits[5]={
2024-05-26 20:31:17 -04:00
_N("right"),
_N("left"),
_N("rear right"),
_N("rear left"),
NULL
2022-04-16 18:24:40 -04:00
};
2022-02-28 18:16:05 -05:00
const char* oneBit[2]={
2024-05-26 20:31:17 -04:00
_N("on"),
NULL
2022-02-28 18:16:05 -05:00
};
const char* es5506EnvelopeModes[3]={
2024-05-26 20:31:17 -04:00
_N("k1 slowdown"),
_N("k2 slowdown"),
NULL
};
const char* es5506ControlModes[3]={
2024-05-26 20:31:17 -04:00
_N("pause"),
_N("reverse"),
NULL
};
2024-03-16 03:59:02 -04:00
const char* minModModeBits[3]={
2024-05-26 20:31:17 -04:00
_N("invert right"),
_N("invert left"),
NULL
2024-03-16 03:59:02 -04:00
};
2022-02-17 13:08:17 -05:00
const int orderedOps[4]={
0, 2, 1, 3
};
2022-05-21 19:36:15 -04:00
const char* singleWSEffects[7]={
2024-05-26 20:31:17 -04:00
_N("None"),
_N("Invert"),
_N("Add"),
_N("Subtract"),
_N("Average"),
_N("Phase"),
_N("Chorus")
2022-04-07 19:27:17 -04:00
};
2022-05-21 19:36:15 -04:00
const char* dualWSEffects[9]={
2024-05-26 20:31:17 -04:00
_N("None (dual)"),
_N("Wipe"),
_N("Fade"),
_N("Fade (ping-pong)"),
_N("Overlay"),
_N("Negative Overlay"),
_N("Slide"),
_N("Mix Chorus"),
_N("Phase Modulation")
2022-04-07 19:27:17 -04:00
};
const char* gbHWSeqCmdTypes[6]={
2024-05-26 20:31:17 -04:00
_N("Envelope"),
_N("Sweep"),
_N("Wait"),
_N("Wait for Release"),
_N("Loop"),
_N("Loop until Release")
2022-04-10 01:01:55 -04:00
};
const char* suHWSeqCmdTypes[7]={
2024-05-26 20:31:17 -04:00
_N("Volume Sweep"),
_N("Frequency Sweep"),
_N("Cutoff Sweep"),
_N("Wait"),
_N("Wait for Release"),
_N("Loop"),
_N("Loop until Release")
};
const char* snesGainModes[5]={
2024-05-26 20:31:17 -04:00
_N("Direct"),
_N("Decrease (linear)"),
_N("Decrease (logarithmic)"),
_N("Increase (linear)"),
_N("Increase (bent line)")
2022-04-10 01:01:55 -04:00
};
2022-11-15 16:09:24 -05:00
const int detuneMap[2][8]={
{-3, -2, -1, 0, 1, 2, 3, 4},
{ 7, 6, 5, 0, 1, 2, 3, 4}
};
const int detuneUnmap[2][11]={
{0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0},
{0, 0, 0, 3, 4, 5, 6, 7, 2, 1, 0}
};
const int kslMap[4]={
0, 2, 1, 3
};
const int _SID3_SPECIAL_WAVES=SID3_NUM_SPECIAL_WAVES-1;
const int _SID3_NUM_CHANNELS=SID3_NUM_CHANNELS;
const int _SID3_NUM_CHANNELS_MINUS_ONE=SID3_NUM_CHANNELS-1;
// do not change these!
// anything other than a checkbox will look ugly!
//
// if you really need to, and have a good rationale (and by good I mean a VERY
// good one), please tell me and we'll sort it out.
2022-04-28 02:31:16 -04:00
const char* macroAbsoluteMode="Fixed";
const char* macroRelativeMode="Relative";
const char* macroQSoundMode="QSound";
2022-04-28 02:31:16 -04:00
const char* macroDummyMode="Bug";
2022-04-10 01:01:55 -04:00
2022-09-09 17:41:00 -04:00
String macroHoverNote(int id, float val, void* u) {
int* macroVal=(int*)u;
if ((macroVal[id]&0xc0000000)==0x40000000 || (macroVal[id]&0xc0000000)==0x80000000) {
if (val<-60 || val>=120) return "???";
return fmt::sprintf("%d: %s",id,noteNames[(int)val+60]);
}
return fmt::sprintf("%d: %d",id,(int)val);
2022-02-17 13:08:17 -05:00
}
2022-09-09 17:41:00 -04:00
String macroHover(int id, float val, void* u) {
2022-10-03 19:40:07 -04:00
return fmt::sprintf("%d: %d",id,(int)val);
2022-02-17 13:08:17 -05:00
}
2022-09-09 17:41:00 -04:00
String macroHoverLoop(int id, float val, void* u) {
2024-05-26 20:31:17 -04:00
if (val>1) return _("Release");
if (val>0) return _("Loop");
2022-02-17 13:08:17 -05:00
return "";
}
2022-09-09 17:41:00 -04:00
String macroHoverBit30(int id, float val, void* u) {
2024-05-26 20:31:17 -04:00
if (val>0) return _("Fixed");
return _("Relative");
2022-02-17 13:08:17 -05:00
}
2022-10-03 19:40:07 -04:00
String macroHoverGain(int id, float val, void* u) {
if (val>=224.0f) {
2024-05-26 20:31:17 -04:00
return fmt::sprintf(_("%d: +%d (exponential)"),id,(int)(val-224));
2022-10-03 19:40:07 -04:00
}
if (val>=192.0f) {
2024-05-26 20:31:17 -04:00
return fmt::sprintf(_("%d: +%d (linear)"),id,(int)(val-192));
2022-10-03 19:40:07 -04:00
}
if (val>=160.0f) {
2024-05-26 20:31:17 -04:00
return fmt::sprintf(_("%d: -%d (exponential)"),id,(int)(val-160));
2022-10-03 19:40:07 -04:00
}
if (val>=128.0f) {
2024-05-26 20:31:17 -04:00
return fmt::sprintf(_("%d: -%d (linear)"),id,(int)(val-128));
2022-10-03 19:40:07 -04:00
}
2024-05-26 20:31:17 -04:00
return fmt::sprintf(_("%d: %d (direct)"),id,(int)val);
2022-10-03 19:40:07 -04:00
}
2022-09-09 17:41:00 -04:00
String macroHoverES5506FilterMode(int id, float val, void* u) {
String mode="???";
switch (((int)val)&3) {
case 0:
mode=_("HP/K2, HP/K2");
break;
case 1:
mode=_("HP/K2, LP/K1");
break;
case 2:
mode=_("LP/K2, LP/K2");
break;
case 3:
mode=_("LP/K2, LP/K1");
break;
default:
break;
}
return fmt::sprintf("%d: %s",id,mode);
}
2022-09-09 17:41:00 -04:00
String macroLFOWaves(int id, float val, void* u) {
2022-02-17 13:08:17 -05:00
switch (((int)val)&3) {
case 0:
2024-05-26 20:31:17 -04:00
return _("Saw");
2022-02-17 13:08:17 -05:00
case 1:
2024-05-26 20:31:17 -04:00
return _("Square");
2022-02-17 13:08:17 -05:00
case 2:
2024-05-26 20:31:17 -04:00
return _("Triangle");
2022-02-17 13:08:17 -05:00
case 3:
2024-05-26 20:31:17 -04:00
return _("Random");
2022-02-17 13:08:17 -05:00
default:
2022-09-25 05:32:34 -04:00
return "???";
2022-02-17 13:08:17 -05:00
}
2022-09-25 05:32:34 -04:00
return "???";
2022-02-17 13:08:17 -05:00
}
String macroVERAWaves(int id, float val, void* u) {
switch (((int)val)&3) {
case 0:
return _("Pulse");
case 1:
return _("Saw");
case 2:
return _("Triangle");
case 3:
return _("Noise");
default:
return "???";
}
return "???";
}
String macroSoundUnitWaves(int id, float val, void* u) {
switch (((int)val)&7) {
case 0:
return _("Square");
case 1:
return _("Saw");
case 2:
return _("Sine");
case 3:
return _("Triangle");
case 4:
return _("Noise");
case 5:
return _("Short Noise");
case 6:
return _("XOR Sine");
case 7:
return _("XOR Triangle");
default:
return "???";
}
return "???";
}
String macroSID3SpecialWaves(int id, float val, void* u) {
if ((int)val<0 || (int)val>=SID3_NUM_SPECIAL_WAVES) return "???";
return _(sid3SpecialWaveforms[(int)val%SID3_NUM_SPECIAL_WAVES]);
}
String macroSID3SourceChan(int id, float val, void* u) {
if ((int)val>SID3_NUM_CHANNELS) return "???";
if ((int)val==SID3_NUM_CHANNELS) {
return _("Self");
} else if ((int)val==SID3_NUM_CHANNELS-1) {
return _("PCM/Wave channel");
} else {
return fmt::sprintf(_("Channel %d"),(int)val+1);
}
}
String macroSID3NoiseLFSR(int id, float val, void* u) {
return _(
"values close to SID2 noise modes:\n\n"
"Mode 1: 524288\n"
"Mode 2: 66\n"
"Mode 3: 541065280"
);
}
String macroSID2WaveMixMode(int id, float val, void* u) {
if ((int)val<0 || (int)val>3) return "???";
return _(sid2WaveMixModes[(int)val]);
}
String macroSID3WaveMixMode(int id, float val, void* u) {
if ((int)val<0 || (int)val>4) return "???";
return _(sid3WaveMixModes[(int)val]);
}
2022-02-28 18:16:05 -05:00
void addAALine(ImDrawList* dl, const ImVec2& p1, const ImVec2& p2, const ImU32 color, float thickness=1.0f) {
ImVec2 pt[2];
pt[0]=p1;
pt[1]=p2;
dl->AddPolyline(pt,2,color,ImDrawFlags_None,thickness);
}
2022-03-27 04:29:45 -04:00
void FurnaceGUI::drawSSGEnv(unsigned char type, const ImVec2& size) {
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_SSG]);
2022-03-27 04:29:45 -04:00
ImGui::ItemSize(size,style.FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID("ssgEnvDisplay"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
switch (type) {
case 0:
for (int i=0; i<4; i++) {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2((float)i/4.0f,0.2));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2((float)(i+1)/4.0f,0.8));
addAALine(dl,pos1,pos2,color);
pos1.x=pos2.x;
if (i<3) addAALine(dl,pos1,pos2,color);
}
break;
case 1: {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,0.2));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.8));
addAALine(dl,pos1,pos2,color);
pos1=ImLerp(rect.Min,rect.Max,ImVec2(1.0,0.8));
addAALine(dl,pos1,pos2,color);
break;
}
case 2: {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,0.2));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.8));
addAALine(dl,pos1,pos2,color);
pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.2));
addAALine(dl,pos1,pos2,color);
pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.8));
addAALine(dl,pos1,pos2,color);
pos1=ImLerp(rect.Min,rect.Max,ImVec2(1.0,0.2));
addAALine(dl,pos1,pos2,color);
break;
}
case 3: {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,0.2));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.8));
addAALine(dl,pos1,pos2,color);
pos1.x=pos2.x;
addAALine(dl,pos1,pos2,color);
pos2=ImLerp(rect.Min,rect.Max,ImVec2(1.0,0.2));
addAALine(dl,pos1,pos2,color);
break;
}
case 4:
for (int i=0; i<4; i++) {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2((float)i/4.0f,0.8));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2((float)(i+1)/4.0f,0.2));
addAALine(dl,pos1,pos2,color);
pos1.x=pos2.x;
if (i<3) addAALine(dl,pos1,pos2,color);
}
break;
case 5: {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,0.8));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.2));
addAALine(dl,pos1,pos2,color);
pos1=ImLerp(rect.Min,rect.Max,ImVec2(1.0,0.2));
addAALine(dl,pos1,pos2,color);
break;
}
case 6: {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,0.8));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.2));
addAALine(dl,pos1,pos2,color);
pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.8));
addAALine(dl,pos1,pos2,color);
pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.2));
addAALine(dl,pos1,pos2,color);
pos1=ImLerp(rect.Min,rect.Max,ImVec2(1.0,0.8));
addAALine(dl,pos1,pos2,color);
break;
}
case 7: {
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,0.8));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.2));
addAALine(dl,pos1,pos2,color);
pos1.x=pos2.x;
addAALine(dl,pos1,pos2,color);
pos2=ImLerp(rect.Min,rect.Max,ImVec2(1.0,0.8));
addAALine(dl,pos1,pos2,color);
break;
}
}
}
}
void FurnaceGUI::drawWaveform(unsigned char type, bool opz, const ImVec2& size) {
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 waveform[65];
const size_t waveformLen=64;
2022-03-27 04:29:45 -04:00
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_WAVE]);
ImGui::ItemSize(size,style.FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID("wsDisplay"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
if (opz) {
switch (type) {
case 0:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=sin(x*2.0*M_PI);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 1:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=pow(sin(x*2.0*M_PI),2.0);
if (x>=0.5) y=-y;
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 2:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=MAX(0.0,sin(x*2.0*M_PI));
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 3:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=pow(MAX(0.0,sin(x*2.0*M_PI)),2.0);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 4:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?0.0:sin(x*4.0*M_PI);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 5:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?0.0:pow(sin(x*4.0*M_PI),2.0);
if (x>=0.25) y=-y;
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 6:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?0.0:fabs(sin(x*4.0*M_PI));
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 7:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?0.0:pow(sin(x*4.0*M_PI),2.0);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
}
} else {
switch (type) {
case 0:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=sin(x*2.0*M_PI);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 1:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=MAX(0.0,sin(x*2.0*M_PI));
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 2:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=fabs(sin(x*2.0*M_PI));
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 3:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=fabs((tan(x*2.0*M_PI)>=0.0)?sin(x*2.0*M_PI):0.0);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 4:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?0.0:sin(x*4.0*M_PI);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 5:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?0.0:fabs(sin(x*4.0*M_PI));
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 6:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=(x>=0.5)?-1.0:1.0;
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
case 7:
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=pow(2.0*(x-0.5),3.0);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
break;
}
}
dl->AddPolyline(waveform,waveformLen+1,color,ImDrawFlags_None,dpiScale);
}
2022-03-27 04:29:45 -04:00
}
typedef double (*WaveFunc) (double a);
WaveFunc waveFuncsIns[]={
sinus,
rectSin,
absSin,
quartSin,
squiSin,
squiAbsSin,
rectSaw,
absSaw,
cubSaw,
rectCubSaw,
absCubSaw,
cubSine,
rectCubSin,
absCubSin,
quartCubSin,
squishCubSin,
squishAbsCubSin,
rectTri,
absTri,
quartTri,
squiTri,
absSquiTri,
cubTriangle,
cubRectTri,
cubAbsTri,
cubQuartTri,
cubSquiTri,
absCubSquiTri
};
void FurnaceGUI::drawWaveformSID3(unsigned char type, const ImVec2& size) {
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 waveform[65];
const size_t waveformLen=64;
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_WAVE]);
ImGui::ItemSize(size,style.FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID("SID3wsDisplay"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
if (type<SID3_NUM_UNIQUE_SPECIAL_WAVES) {
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=waveFuncsIns[type](x*2.0*M_PI);
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
} else if (type>=SID3_NUM_UNIQUE_SPECIAL_WAVES && type<SID3_NUM_UNIQUE_SPECIAL_WAVES*2) {
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=waveFuncsIns[type-SID3_NUM_UNIQUE_SPECIAL_WAVES](x*2.0*M_PI);
y*=2.0f; // clipping
if (y>1.0f) y=1.0f;
if (y<-1.0f) y=-1.0f;
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.48));
}
} else {
if (type==SID3_NUM_UNIQUE_SPECIAL_WAVES*2) {
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=triangle(x*2.0*M_PI);
y*=2.0f; // clipping
if (y>1.0f) y=1.0f;
if (y<-1.0f) y=-1.0f;
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
}
if (type==SID3_NUM_UNIQUE_SPECIAL_WAVES*2+1) {
for (size_t i=0; i<=waveformLen; i++) {
float x=(float)i/(float)waveformLen;
float y=saw(x*2.0*M_PI);
y*=2.0f; // clipping
if (y>1.0f) y=1.0f;
if (y<-1.0f) y=-1.0f;
waveform[i]=ImLerp(rect.Min,rect.Max,ImVec2(x,0.5-y*0.4));
}
}
}
dl->AddPolyline(waveform,waveformLen+1,color,ImDrawFlags_None,dpiScale);
}
}
2022-02-17 13:08:17 -05:00
void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size) {
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 colorM=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_MOD]);
ImU32 colorC=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_CAR]);
ImU32 colorL=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ALG_LINE]);
2022-02-17 13:08:17 -05:00
ImGui::ItemSize(size,style.FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID("alg"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ALG_BG]),true,style.FrameRounding);
2022-02-17 13:08:17 -05:00
const float circleRadius=6.0f*dpiScale+1.0f;
switch (algType) {
case FM_ALGS_4OP:
switch (alg) {
case 0: { // 1 > 2 > 3 > 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.2,0.5));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.4,0.5));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.6,0.5));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.8,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos3,colorL);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("1").x*0.5;
pos2.x-=ImGui::CalcTextSize("2").x*0.5;
pos3.x-=ImGui::CalcTextSize("3").x*0.5;
pos4.x-=ImGui::CalcTextSize("4").x*0.5;
pos1.y-=ImGui::CalcTextSize("1").y+circleRadius;
pos2.y-=ImGui::CalcTextSize("2").y+circleRadius;
pos3.y-=ImGui::CalcTextSize("3").y+circleRadius;
pos4.y-=ImGui::CalcTextSize("4").y+circleRadius;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 1: { // (1+2) > 3 > 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.3));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.7));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.5));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos3,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos3,colorL);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-17 13:08:17 -05:00
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos1.x=pos2.x;
pos3.x-=ImGui::CalcTextSize("3").x*0.5;
pos4.x-=ImGui::CalcTextSize("4").x*0.5;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y+circleRadius;
pos4.y-=ImGui::CalcTextSize("4").y+circleRadius;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 2: { // 1+(2>3) > 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.3));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.7));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.7));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos4,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos3,colorL);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x*0.5;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y+circleRadius;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 3: { // (1>2)+3 > 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.3));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.3));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.7));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos4,colorL);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x*0.5;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y+circleRadius;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 4: { // (1>2) + (3>4)
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.3));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.3));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.7));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.7));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos5,colorL);
addAALine(dl,pos4,pos5,colorL);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y*0.5;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorC,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 5: { // 1 > (2+3+4)
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.5));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.25));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.5));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.75));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,colorL);
addAALine(dl,pos1,pos3,colorL);
addAALine(dl,pos1,pos4,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos5,colorL);
addAALine(dl,pos3,pos5,colorL);
addAALine(dl,pos4,pos5,colorL);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y*0.5;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorC,"2");
dl->AddText(pos3,colorC,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 6: { // (1>2) + 3 + 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.25));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.25));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.5));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.75));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos2,pos5,colorL);
addAALine(dl,pos3,pos5,colorL);
addAALine(dl,pos4,pos5,colorL);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y*0.5;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorC,"2");
dl->AddText(pos3,colorC,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
case 7: { // 1 + 2 + 3 + 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.2));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.35,0.4));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.45,0.6));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.55,0.8));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorC);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos5,colorL);
addAALine(dl,pos2,pos5,colorL);
addAALine(dl,pos3,pos5,colorL);
addAALine(dl,pos4,pos5,colorL);
2022-02-17 13:08:17 -05:00
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y*0.5;
dl->AddText(pos1,colorC,"1");
dl->AddText(pos2,colorC,"2");
dl->AddText(pos3,colorC,"3");
dl->AddText(pos4,colorC,"4");
2022-02-17 13:08:17 -05:00
break;
}
}
break;
case FM_ALGS_2OP_OPL:
switch (alg) {
case 0: { // 1 > 2
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.33,0.5));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.67,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x+=circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorC,"2");
break;
}
case 1: { // 1 + 2
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.33,0.5));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.67,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorC);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x+=circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
dl->AddText(pos1,colorC,"1");
dl->AddText(pos2,colorC,"2");
break;
}
}
break;
2022-03-15 01:09:45 -04:00
case FM_ALGS_4OP_OPL:
switch (alg) {
case 0: { // 1 > 2 > 3 > 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.2,0.5));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.4,0.5));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.6,0.5));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.8,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos2,pos3,colorL);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-03-15 01:09:45 -04:00
pos1.x-=ImGui::CalcTextSize("1").x*0.5;
pos2.x-=ImGui::CalcTextSize("2").x*0.5;
pos3.x-=ImGui::CalcTextSize("3").x*0.5;
pos4.x-=ImGui::CalcTextSize("4").x*0.5;
pos1.y-=ImGui::CalcTextSize("1").y+circleRadius;
pos2.y-=ImGui::CalcTextSize("2").y+circleRadius;
pos3.y-=ImGui::CalcTextSize("3").y+circleRadius;
pos4.y-=ImGui::CalcTextSize("4").y+circleRadius;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-03-15 01:09:45 -04:00
break;
}
case 1: { // 1 + (2 > 3 > 4)
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.4,0.3));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.2,0.7));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.4,0.7));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.6,0.7));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.8,0.7));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorC);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorC);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos1,pos5,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos2,pos3,colorL);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos4,pos5,colorL);
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x*0.5;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y+circleRadius;
dl->AddText(pos1,colorC,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-03-15 01:09:45 -04:00
break;
}
case 2: { // (1>2) + (3>4)
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.3));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.3));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.7));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.7));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorM);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos1,pos2,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorM);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos3,pos4,colorL);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos2,pos5,colorL);
addAALine(dl,pos4,pos5,colorL);
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y*0.5;
dl->AddText(pos1,colorM,"1");
dl->AddText(pos2,colorC,"2");
dl->AddText(pos3,colorM,"3");
dl->AddText(pos4,colorC,"4");
2022-03-15 01:09:45 -04:00
break;
}
case 3: { // 1 + (2 > 3) + 4
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.25));
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.25,0.5));
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.5));
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.5,0.75));
ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5));
dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,colorC);
dl->AddCircle(pos1,6.0f*dpiScale+1.0f,colorC);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos2,pos3,colorL);
dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,colorM);
dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,colorC);
dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,colorC);
2022-03-15 01:09:45 -04:00
addAALine(dl,pos1,pos5,colorL);
addAALine(dl,pos3,pos5,colorL);
addAALine(dl,pos4,pos5,colorL);
pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale;
pos3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0*dpiScale;
pos4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0*dpiScale;
pos1.y-=ImGui::CalcTextSize("1").y*0.5;
pos2.y-=ImGui::CalcTextSize("2").y*0.5;
pos3.y-=ImGui::CalcTextSize("3").y*0.5;
pos4.y-=ImGui::CalcTextSize("4").y*0.5;
dl->AddText(pos1,colorC,"1");
dl->AddText(pos2,colorM,"2");
dl->AddText(pos3,colorC,"3");
dl->AddText(pos4,colorC,"4");
2022-03-15 01:09:45 -04:00
break;
}
}
break;
2022-02-17 13:08:17 -05:00
default:
break;
}
}
}
2023-10-16 15:57:04 -04:00
void FurnaceGUI::drawESFMAlgorithm(DivInstrumentESFM& esfm, const ImVec2& size) {
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 colorM=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_MOD]);
ImU32 colorC=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_CAR]);
ImU32 colorsL[8];
for (int i=0; i<8; i++){
float alpha=(float)i/7.0f;
ImVec4 color=uiColors[GUI_COLOR_FM_ALG_LINE];
color.w *= alpha;
colorsL[i]=ImGui::GetColorU32(color);
}
ImGui::ItemSize(size,style.FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID("alg"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ALG_BG]),true,style.FrameRounding);
const float circleRadius=6.0f*dpiScale+1.0f;
//int modFb = esfm.op[0].modIn&7;
int mod12 = esfm.op[1].modIn&7;
int mod23 = esfm.op[2].modIn&7;
int mod34 = esfm.op[3].modIn&7;
int out1 = esfm.op[0].outLvl&7;
int out2 = esfm.op[1].outLvl&7;
int out3 = esfm.op[2].outLvl&7;
int out4 = esfm.op[3].outLvl&7;
bool isMod[4];
for (int i=0; i<4; i++) {
2023-10-22 10:46:34 -04:00
DivInstrumentESFM::Operator& opE=esfm.op[i];
2023-10-16 15:57:04 -04:00
isMod[i]=true;
if (opE.outLvl==7) isMod[i]=false;
else if (opE.outLvl>0) {
if (i==3) isMod[i]=false;
else {
DivInstrumentESFM::Operator& opENext=esfm.op[i+1];
if (opENext.modIn==0) isMod[i]=false;
2023-10-22 10:46:34 -04:00
else if ((opE.outLvl-opENext.modIn)>=2) isMod[i]=false;
2023-10-16 15:57:04 -04:00
}
}
}
ImVec2 posOp1=ImLerp(rect.Min,rect.Max,ImVec2(0.2f,0.25f));
ImVec2 posOp2=ImLerp(rect.Min,rect.Max,ImVec2(0.4f,0.25f));
ImVec2 posOp3=ImLerp(rect.Min,rect.Max,ImVec2(0.6f,0.25f));
ImVec2 posOp4=ImLerp(rect.Min,rect.Max,ImVec2(0.8f,0.25f));
ImVec2 posBusbarOp1=ImLerp(rect.Min,rect.Max,ImVec2(0.2f,0.75f));
ImVec2 posBusbarOp2=ImLerp(rect.Min,rect.Max,ImVec2(0.4f,0.75f));
ImVec2 posBusbarOp3=ImLerp(rect.Min,rect.Max,ImVec2(0.6f,0.75f));
ImVec2 posBusbarOp4=ImLerp(rect.Min,rect.Max,ImVec2(0.8f,0.75f));
ImVec2 posBusbarStart=ImLerp(rect.Min,rect.Max,ImVec2(0.15f,0.75f));
ImVec2 posBusbarEnd=ImLerp(rect.Min,rect.Max,ImVec2(0.85f,0.75f));
bool busbarStartSeen=false;
for (int i=0; i<4; i++) {
DivInstrumentESFM::Operator& opE=esfm.op[i];
if (opE.outLvl>0) {
if (!busbarStartSeen) {
busbarStartSeen=true;
posBusbarStart=ImLerp(rect.Min,rect.Max,ImVec2(0.15f+0.2f*i,0.75f));
}
posBusbarEnd=ImLerp(rect.Min,rect.Max,ImVec2(0.25f+0.2f*i,0.75f));
}
}
if (mod12) addAALine(dl,posOp1,posOp2,colorsL[mod12]);
if (mod23) addAALine(dl,posOp2,posOp3,colorsL[mod23]);
if (mod34) addAALine(dl,posOp3,posOp4,colorsL[mod34]);
if (out1) addAALine(dl,posOp1,posBusbarOp1,colorsL[out1]);
if (out2) addAALine(dl,posOp2,posBusbarOp2,colorsL[out2]);
if (out3) addAALine(dl,posOp3,posBusbarOp3,colorsL[out3]);
if (out4) addAALine(dl,posOp4,posBusbarOp4,colorsL[out4]);
addAALine(dl,posBusbarStart,posBusbarEnd,colorsL[2]);
// addAALine(dl,posBusbarEnd,posBusbarEnd+ImVec2(-8.0f*dpiScale,-4.0f*dpiScale),colorsL[2]);
// addAALine(dl,posBusbarEnd,posBusbarEnd+ImVec2(-8.0f*dpiScale,4.0f*dpiScale),colorsL[2]);
// addAALine(dl,posBusbarStart+ImVec2(4.0f*dpiScale,-4.0f*dpiScale),posBusbarStart+ImVec2(4.0f*dpiScale,4.0f*dpiScale),colorsL[2]);
dl->AddCircle(posOp1,6.0f*dpiScale+1.0f,isMod[0]?colorM:colorC);
dl->AddCircleFilled(posOp1,4.0f*dpiScale+1.0f,isMod[0]?colorM:colorC);
dl->AddCircleFilled(posOp2,4.0f*dpiScale+1.0f,isMod[1]?colorM:colorC);
dl->AddCircleFilled(posOp3,4.0f*dpiScale+1.0f,isMod[2]?colorM:colorC);
dl->AddCircleFilled(posOp4,4.0f*dpiScale+1.0f,isMod[3]?colorM:colorC);
posOp1.x-=ImGui::CalcTextSize("1").x+circleRadius+3.0f*dpiScale;
posOp2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0f*dpiScale;
posOp3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0f*dpiScale;
posOp4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0f*dpiScale;
posOp1.y-=ImGui::CalcTextSize("1").y*0.5f;
posOp2.y-=ImGui::CalcTextSize("2").y*0.5f;
posOp3.y-=ImGui::CalcTextSize("3").y*0.5f;
posOp4.y-=ImGui::CalcTextSize("4").y*0.5f;
dl->AddText(posOp1,isMod[0]?colorM:colorC,"1");
dl->AddText(posOp2,isMod[1]?colorM:colorC,"2");
dl->AddText(posOp3,isMod[2]?colorM:colorC,"3");
dl->AddText(posOp4,isMod[3]?colorM:colorC,"4");
}
}
2022-09-28 20:33:16 -04:00
void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, float maxRr, const ImVec2& size, unsigned short instType) {
2022-02-17 13:08:17 -05:00
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE]);
ImU32 colorR=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE_RELEASE]); // Relsease triangle
ImU32 colorS=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE_SUS_GUIDE]); // Sustain horiz/vert line color
2022-02-17 13:08:17 -05:00
ImGui::ItemSize(size,style.FramePadding.y);
2022-04-17 02:15:34 -04:00
if (ImGui::ItemAdd(rect,ImGui::GetID("fmEnv"))) {
2022-02-17 13:08:17 -05:00
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
//Adjust for OPLL global sustain setting
if (instType==DIV_INS_OPLL && algOrGlobalSus==1.0){
rr = 5.0;
}
//calculate x positions
2022-02-28 18:16:05 -05:00
float arPos=float(maxArDr-ar)/maxArDr; //peak of AR, start of DR
float drPos=arPos+((sl/15.0)*(float(maxArDr-dr)/maxArDr)); //end of DR, start of D2R
float d2rPos=drPos+(((15.0-sl)/15.0)*(float(31.0-d2r)/31.0)); //End of D2R
2022-09-28 20:33:16 -04:00
float rrPos=(float(maxRr-rr)/float(maxRr)); //end of RR
2022-02-17 13:08:17 -05:00
//shrink all the x positions horizontally
arPos/=2.0;
drPos/=2.0;
d2rPos/=2.0;
rrPos/=1.0;
2022-02-21 17:23:07 -05:00
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,1.0)); //the bottom corner
2022-02-28 18:16:05 -05:00
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(arPos,(tl/maxTl))); //peak of AR, start of DR
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(drPos,(float)((tl/maxTl)+(sl/15.0)-((tl/maxTl)*(sl/15.0))))); //end of DR, start of D2R
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(d2rPos,1.0)); //end of D2R
2022-02-28 18:16:05 -05:00
ImVec2 posRStart=ImLerp(rect.Min,rect.Max,ImVec2(0.0,(tl/maxTl))); //release start
2022-02-21 23:17:19 -05:00
ImVec2 posREnd=ImLerp(rect.Min,rect.Max,ImVec2(rrPos,1.0));//release end
2022-02-28 18:16:05 -05:00
ImVec2 posSLineHEnd=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)((tl/maxTl)+(sl/15.0)-((tl/maxTl)*(sl/15.0))))); //sustain horizontal line end
2022-02-22 11:55:13 -05:00
ImVec2 posSLineVEnd=ImLerp(rect.Min,rect.Max,ImVec2(drPos,1.0)); //sustain vertical line end
2022-04-10 01:01:55 -04:00
ImVec2 posDecayRate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(tl/maxTl))); //Height of the peak of AR, forever
ImVec2 posDecay2Rate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)((tl/maxTl)+(sl/15.0)-((tl/maxTl)*(sl/15.0))))); //Height of the peak of SR, forever
2022-02-21 16:31:52 -05:00
2022-02-28 18:16:05 -05:00
//dl->Flags=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
if (ar==0.0) { //if AR = 0, the envelope never starts
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos4,color); //draw line on ground
} else if (dr==0.0 && sl!=0.0) { //if DR = 0 and SL is not 0, then the envelope stays at max volume forever
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything
2022-02-28 18:16:05 -05:00
//addAALine(dl,pos3,posSLineHEnd,colorS); //draw horiz line through sustain level
//addAALine(dl,pos3,posSLineVEnd,colorS); //draw vert. line through sustain level
addAALine(dl,pos1,pos2,color); //A
addAALine(dl,pos2,posDecayRate0Pt,color); //Line from A to end of graph
} else if (d2r==0.0 || ((instType==DIV_INS_OPL || instType==DIV_INS_SNES || instType==DIV_INS_ESFM) && sus==1.0) || (instType==DIV_INS_OPLL && egt!=0.0)) { //envelope stays at the sustain level forever
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything
addAALine(dl,pos3,posSLineHEnd,colorR); //draw horiz line through sustain level
addAALine(dl,pos3,posSLineVEnd,colorR); //draw vert. line through sustain level
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,color); //A
addAALine(dl,pos2,pos3,color); //D
addAALine(dl,pos3,posDecay2Rate0Pt,color); //Line from D to end of graph
} else { //draw graph normally
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything
addAALine(dl,pos3,posSLineHEnd,colorR); //draw horiz line through sustain level
addAALine(dl,pos3,posSLineVEnd,colorR); //draw vert. line through sustain level
2022-02-28 18:16:05 -05:00
addAALine(dl,pos1,pos2,color); //A
addAALine(dl,pos2,pos3,color); //D
addAALine(dl,pos3,pos4,color); //D2
}
2022-02-28 18:16:05 -05:00
//dl->Flags^=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
2022-02-17 13:08:17 -05:00
}
}
void FurnaceGUI::drawSID3Env(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, float maxRr, const ImVec2& size, unsigned short instType) {
ImDrawList* dl=ImGui::GetWindowDrawList();
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE]);
ImU32 colorR=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE_RELEASE]); // Relsease triangle
ImU32 colorS=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE_SUS_GUIDE]); // Sustain horiz/vert line color
ImGui::ItemSize(size,style.FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID("fmEnv"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
// Adjust for OPLL global sustain setting
if (instType==DIV_INS_OPLL && algOrGlobalSus==1.0) {
rr=5.0;
}
// calculate x positions
float arPos=float(maxArDr-(float)ar)/maxArDr; // peak of AR, start of DR
float drPos=arPos+(((float)sl/255.0)*(float(maxArDr-(float)dr)/maxArDr)); // end of DR, start of D2R
float d2rPos=drPos+(((255.0-(float)sl)/255.0)*(float(255.0-(float)d2r)/255.0)); // End of D2R
float rrPos=(float(maxRr-(float)rr)/float(maxRr)); // end of RR
// shrink all the x positions horizontally
arPos/=2.0;
drPos/=2.0;
d2rPos/=2.0;
rrPos/=1.0;
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,1.0)); // the bottom corner
ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(arPos,((float)tl/maxTl))); // peak of AR, start of DR
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(drPos,(float)(((float)tl/maxTl)+((float)sl/255.0)-(((float)tl/maxTl)*((float)sl/255.0))))); // end of DR, start of D2R
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(d2rPos,1.0)); // end of D2R
ImVec2 posRStart=ImLerp(rect.Min,rect.Max,ImVec2(0.0,((float)tl/maxTl))); // release start
ImVec2 posREnd=ImLerp(rect.Min,rect.Max,ImVec2(rrPos,1.0));// release end
ImVec2 posSLineHEnd=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)(((float)tl/maxTl)+((float)sl/255.0)-(((float)tl/maxTl)*((float)sl/255.0))))); // sustain horizontal line end
ImVec2 posSLineVEnd=ImLerp(rect.Min,rect.Max,ImVec2(drPos,1.0)); // sustain vertical line end
ImVec2 posDecayRate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,((float)tl/maxTl))); // Height of the peak of AR, forever
ImVec2 posDecay2Rate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)(((float)tl/maxTl)+((float)sl/255.0)-(((float)tl/maxTl)*((float)sl/255.0))))); // Height of the peak of SR, forever
// dl->Flags=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
if ((float)ar==0.0) { // if AR = 0, the envelope never starts
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); // draw release as shaded triangle behind everything
addAALine(dl,pos1,pos4,color); // draw line on ground
} else if ((float)dr==0.0 && (float)sl!=0.0) { // if DR = 0 and SL is not 0, then the envelope stays at max volume forever
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); // draw release as shaded triangle behind everything
// addAALine(dl,pos3,posSLineHEnd,colorS); // draw horiz line through sustain level
// addAALine(dl,pos3,posSLineVEnd,colorS); // draw vert. line through sustain level
addAALine(dl,pos1,pos2,color); // A
addAALine(dl,pos2,posDecayRate0Pt,color); // Line from A to end of graph
} else if ((float)d2r==0.0 || ((instType==DIV_INS_OPL || instType==DIV_INS_SNES || instType == DIV_INS_ESFM) && sus==1.0) || (instType==DIV_INS_OPLL && egt!=0.0)) { // envelope stays at the sustain level forever
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); // draw release as shaded triangle behind everything
addAALine(dl,pos3,posSLineHEnd,colorR); // draw horiz line through sustain level
addAALine(dl,pos3,posSLineVEnd,colorR); // draw vert. line through sustain level
addAALine(dl,pos1,pos2,color); // A
addAALine(dl,pos2,pos3,color); // D
addAALine(dl,pos3,posDecay2Rate0Pt,color); // Line from D to end of graph
} else { // draw graph normally
dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); // draw release as shaded triangle behind everything
addAALine(dl,pos3,posSLineHEnd,colorR); // draw horiz line through sustain level
addAALine(dl,pos3,posSLineVEnd,colorR); // draw vert. line through sustain level
addAALine(dl,pos1,pos2,color); // A
addAALine(dl,pos2,pos3,color); // D
addAALine(dl,pos3,pos4,color); // D2
}
//dl->Flags^=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex;
}
}
2022-04-17 00:58:29 -04:00
void FurnaceGUI::drawGBEnv(unsigned char vol, unsigned char len, unsigned char sLen, bool dir, const ImVec2& size) {
2022-04-17 02:15:34 -04:00
ImDrawList* dl=ImGui::GetWindowDrawList();
2022-04-17 00:58:29 -04:00
ImGuiWindow* window=ImGui::GetCurrentWindow();
ImVec2 minArea=window->DC.CursorPos;
ImVec2 maxArea=ImVec2(
minArea.x+size.x,
minArea.y+size.y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
2022-04-17 02:15:34 -04:00
ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE]);
2022-04-17 00:58:29 -04:00
//ImU32 colorS=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ENVELOPE_SUS_GUIDE]); // Sustain horiz/vert line color
ImGui::ItemSize(size,style.FramePadding.y);
2022-04-17 02:15:34 -04:00
if (ImGui::ItemAdd(rect,ImGui::GetID("gbEnv"))) {
2022-04-17 00:58:29 -04:00
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
2022-04-17 02:15:34 -04:00
float volY=1.0-((float)vol/15.0);
float lenPos=(sLen>62)?1.0:((float)sLen/384.0);
float envEndPoint=((float)len/7.0)*((float)(dir?(15-vol):vol)/15.0);
ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,volY));
ImVec2 pos2;
if (dir) {
if (len>0) {
if (lenPos<envEndPoint) {
pos2=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,volY*(1.0-(lenPos/envEndPoint))));
} else {
pos2=ImLerp(rect.Min,rect.Max,ImVec2(envEndPoint,0.0));
}
} else {
pos2=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,volY));
}
} else {
if (len>0) {
if (lenPos<envEndPoint) {
pos2=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,volY+(1.0-volY)*(lenPos/envEndPoint)));
} else {
pos2=ImLerp(rect.Min,rect.Max,ImVec2(envEndPoint,1.0));
}
} else {
pos2=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,volY));
}
}
ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,(len>0 || sLen<63)?((dir && sLen>62)?0.0:1.0):volY));
addAALine(dl,pos1,pos2,color);
if (lenPos>=envEndPoint && sLen<63 && dir) {
pos3=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,0.0));
addAALine(dl,pos2,pos3,color);
ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(lenPos,1.0));
addAALine(dl,pos3,pos4,color);
} else {
addAALine(dl,pos2,pos3,color);
}
2022-04-17 00:58:29 -04:00
}
}
2022-02-17 13:08:17 -05:00
#define P(x) if (x) { \
MARK_MODIFIED; \
2022-02-17 13:08:17 -05:00
e->notifyInsChange(curIns); \
updateFMPreview=true; \
2022-02-17 13:08:17 -05:00
}
#define PARAMETER MARK_MODIFIED; e->notifyInsChange(curIns); updateFMPreview=true;
2022-02-17 13:08:17 -05:00
2022-05-07 19:30:16 -04:00
String genericGuide(float value) {
return fmt::sprintf("%d",(int)value);
}
2022-02-17 13:08:17 -05:00
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;
}
2022-09-22 02:18:41 -04:00
2023-08-21 20:56:22 -04:00
void FurnaceGUI::kvsConfig(DivInstrument* ins, bool supportsKVS) {
if (fmPreviewOn) {
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("left click to restart\nmiddle click to pause\nright click to see algorithm"));
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
updateFMPreview=true;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) {
fmPreviewPaused=!fmPreviewPaused;
}
2023-08-21 20:56:22 -04:00
} else if (supportsKVS) {
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("left click to configure TL scaling\nright click to see FM preview"));
}
2023-08-21 20:56:22 -04:00
} else {
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("right click to see FM preview"));
2023-08-21 20:56:22 -04:00
}
2022-09-22 02:18:41 -04:00
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
fmPreviewOn=!fmPreviewOn;
}
2023-08-21 18:24:41 -04:00
if (ImGui::IsItemHovered() && CHECK_LONG_HOLD) {
NOTIFY_LONG_HOLD;
fmPreviewOn=!fmPreviewOn;
}
2023-08-21 20:56:22 -04:00
if (!fmPreviewOn && supportsKVS) {
int opCount=4;
if (ins->type==DIV_INS_OPLL) opCount=2;
if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2;
if (ImGui::BeginPopupContextItem("IKVSOpt",ImGuiPopupFlags_MouseButtonLeft)) {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("operator level changes with volume?"));
if (ImGui::BeginTable("KVSTable",4,ImGuiTableFlags_BordersInner)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch);
for (int i=0; i<4; i++) {
2024-01-20 12:09:51 -05:00
int o=(opCount==4 && ins->type!=DIV_INS_ESFM)?orderedOps[i]:i;
if (!(i&1)) ImGui::TableNextRow();
2024-05-26 20:31:17 -04:00
const char* label=_("AUTO##OPKVS");
if (ins->fm.op[o].kvs==0) {
2024-05-26 20:31:17 -04:00
label=_("NO##OPKVS");
} else if (ins->fm.op[o].kvs==1) {
2024-05-26 20:31:17 -04:00
label=_("YES##OPKVS");
}
ImGui::TableNextColumn();
ImGui::Text("%d",i+1);
ImGui::TableNextColumn();
ImGui::PushID(o);
if (ImGui::Button(label,ImVec2(ImGui::GetContentRegionAvail().x,0.0f))) {
if (++ins->fm.op[o].kvs>2) ins->fm.op[o].kvs=0;
PARAMETER;
}
ImGui::PopID();
2022-09-22 02:18:41 -04:00
}
ImGui::EndTable();
2022-09-22 02:18:41 -04:00
}
ImGui::EndPopup();
2022-09-22 02:18:41 -04:00
}
}
}
void FurnaceGUI::drawFMPreview(const ImVec2& size) {
float asFloat[FM_PREVIEW_SIZE];
for (int i=0; i<FM_PREVIEW_SIZE; i++) {
asFloat[i]=(float)fmPreview[i]/8192.0f;
}
ImGui::PlotLines("##DebugFMPreview",asFloat,FM_PREVIEW_SIZE,0,NULL,-1.0,1.0,size);
}
#define MACRO_VZOOM i.ins->temp.vZoom[i.macro->macroType]
#define MACRO_VSCROLL i.ins->temp.vScroll[i.macro->macroType]
void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float availableWidth, int index) {
static float asFloat[256];
static int asInt[256];
static float loopIndicator[256];
static float bit30Indicator[256];
static bool doHighlight[256];
if ((i.macro->open&6)==0) {
for (int j=0; j<256; j++) {
bit30Indicator[j]=0;
if (j+macroDragScroll>=i.macro->len) {
asFloat[j]=0;
asInt[j]=0;
} else {
asFloat[j]=deBit30(i.macro->val[j+macroDragScroll]);
asInt[j]=deBit30(i.macro->val[j+macroDragScroll]);
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)) {
loopIndicator[j]=0;
} else {
loopIndicator[j]=((i.macro->loop!=255 && (j+macroDragScroll)>=i.macro->loop))|((i.macro->rel!=255 && (j+macroDragScroll)==i.macro->rel)<<1);
}
2022-05-07 19:30:16 -04:00
}
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
if (MACRO_VZOOM<1) {
if (i.macro->macroType==DIV_MACRO_ARP || i.isArp) {
MACRO_VZOOM=24;
MACRO_VSCROLL=120-12;
} else if (i.macro->macroType==DIV_MACRO_PITCH || i.isPitch) {
MACRO_VZOOM=128;
MACRO_VSCROLL=2048-64;
} else {
MACRO_VZOOM=i.max-i.min;
MACRO_VSCROLL=0;
}
2022-05-07 00:52:26 -04:00
}
if (MACRO_VZOOM>(i.max-i.min)) {
MACRO_VZOOM=i.max-i.min;
2022-05-07 00:52:26 -04:00
}
memset(doHighlight,0,256*sizeof(bool));
if (e->isRunning()) for (int j=0; j<e->getTotalChannelCount(); j++) {
DivChannelState* chanState=e->getChanState(j);
if (chanState==NULL) continue;
2022-05-07 00:52:26 -04:00
if (chanState->keyOff) continue;
if (chanState->lastIns!=curIns) continue;
DivMacroInt* macroInt=e->getMacroInt(j);
if (macroInt==NULL) continue;
2023-10-06 00:51:34 -04:00
DivMacroStruct* macroStruct=macroInt->structByType(i.macro->macroType);
if (macroStruct==NULL) continue;
if (macroStruct->lastPos>i.macro->len) continue;
if (macroStruct->lastPos<macroDragScroll) continue;
if (macroStruct->lastPos>255) continue;
if (!macroStruct->actualHad) continue;
2022-10-07 17:47:18 -04:00
doHighlight[macroStruct->lastPos-macroDragScroll]=true;
2022-05-07 19:30:16 -04:00
}
if (i.isBitfield) {
PlotBitfield("##IMacro",asInt,totalFit,0,i.bitfieldBits,i.max,ImVec2(availableWidth,(i.macro->open&1)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),doHighlight,uiColors[GUI_COLOR_MACRO_HIGHLIGHT],i.color,i.hoverFunc,i.hoverFuncUser);
} else {
PlotCustom("##IMacro",asFloat,totalFit,macroDragScroll,NULL,i.min+MACRO_VSCROLL,i.min+MACRO_VSCROLL+MACRO_VZOOM,ImVec2(availableWidth,(i.macro->open&1)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),i.color,i.macro->len-macroDragScroll,i.hoverFunc,i.hoverFuncUser,i.blockMode,(i.macro->open&1)?genericGuide:NULL,doHighlight,uiColors[GUI_COLOR_MACRO_HIGHLIGHT]);
2022-05-07 00:52:26 -04:00
}
if ((i.macro->open&1) && (ImGui::IsItemClicked(ImGuiMouseButton_Left) || ImGui::IsItemClicked(ImGuiMouseButton_Right))) {
ImGui::InhibitInertialScroll();
macroDragStart=ImGui::GetItemRectMin();
macroDragAreaSize=ImVec2(availableWidth,i.height*dpiScale);
if (i.isBitfield) {
macroDragMin=i.min;
macroDragMax=i.max;
} else {
macroDragMin=i.min+MACRO_VSCROLL;
macroDragMax=i.min+MACRO_VSCROLL+MACRO_VZOOM;
}
macroDragBitMode=i.isBitfield;
macroDragInitialValueSet=false;
macroDragInitialValue=false;
macroDragLen=totalFit;
macroDragActive=true;
macroDragBit30=i.bit30;
macroDragSettingBit30=false;
macroDragTarget=i.macro->val;
macroDragChar=false;
macroDragLineMode=(i.isBitfield)?false:ImGui::IsItemClicked(ImGuiMouseButton_Right);
macroDragLineInitial=ImVec2(0,0);
lastMacroDesc=i;
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
2022-05-07 00:52:26 -04:00
}
if ((i.macro->open&1)) {
if (ImGui::IsItemHovered()) {
if (ctrlWheeling) {
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
MACRO_VZOOM+=wheelY*(1+(MACRO_VZOOM>>4));
if (MACRO_VZOOM<1) MACRO_VZOOM=1;
if (MACRO_VZOOM>(i.max-i.min)) MACRO_VZOOM=i.max-i.min;
if ((MACRO_VSCROLL+MACRO_VZOOM)>(i.max-i.min)) {
MACRO_VSCROLL=(i.max-i.min)-MACRO_VZOOM;
2022-10-07 17:47:18 -04:00
}
} else if (settings.autoMacroStepSize==0) {
macroPointSize+=wheelY;
if (macroPointSize<1) macroPointSize=1;
if (macroPointSize>256) macroPointSize=256;
2022-10-07 17:47:18 -04:00
}
} else if ((ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) && wheelY!=0) {
MACRO_VSCROLL+=wheelY*(1+(MACRO_VZOOM>>4));
if (MACRO_VSCROLL<0) MACRO_VSCROLL=0;
if (MACRO_VSCROLL>((i.max-i.min)-MACRO_VZOOM)) MACRO_VSCROLL=(i.max-i.min)-MACRO_VZOOM;
2022-05-07 00:52:26 -04:00
}
}
2022-02-17 13:08:17 -05:00
// slider
if (!i.isBitfield) {
if (settings.oldMacroVSlider) {
ImGui::SameLine(0.0f);
if (ImGui::VSliderInt("##IMacroVScroll",ImVec2(20.0f*dpiScale,i.height*dpiScale),&MACRO_VSCROLL,0,(i.max-i.min)-MACRO_VZOOM,"",ImGuiSliderFlags_NoInput)) {
if (MACRO_VSCROLL<0) MACRO_VSCROLL=0;
if (MACRO_VSCROLL>((i.max-i.min)-MACRO_VZOOM)) MACRO_VSCROLL=(i.max-i.min)-MACRO_VZOOM;
2022-10-07 05:11:45 -04:00
}
if (ImGui::IsItemHovered() && ctrlWheeling) {
MACRO_VSCROLL+=wheelY*(1+(MACRO_VZOOM>>4));
if (MACRO_VSCROLL<0) MACRO_VSCROLL=0;
if (MACRO_VSCROLL>((i.max-i.min)-MACRO_VZOOM)) MACRO_VSCROLL=(i.max-i.min)-MACRO_VZOOM;
2022-10-07 05:11:45 -04:00
}
} else {
ImS64 scrollV=(i.max-i.min-MACRO_VZOOM)-MACRO_VSCROLL;
ImS64 availV=MACRO_VZOOM;
ImS64 contentsV=(i.max-i.min);
ImGui::SameLine(0.0f);
ImGui::SetCursorPosX(ImGui::GetCursorPosX()-ImGui::GetStyle().ItemSpacing.x);
ImRect scrollbarPos=ImRect(ImGui::GetCursorScreenPos(),ImGui::GetCursorScreenPos());
scrollbarPos.Max.x+=ImGui::GetStyle().ScrollbarSize;
scrollbarPos.Max.y+=i.height*dpiScale;
ImGui::Dummy(ImVec2(ImGui::GetStyle().ScrollbarSize,i.height*dpiScale));
if (ImGui::IsItemHovered() && ctrlWheeling) {
MACRO_VSCROLL+=wheelY*(1+(MACRO_VZOOM>>4));
if (MACRO_VSCROLL<0) MACRO_VSCROLL=0;
if (MACRO_VSCROLL>((i.max-i.min)-MACRO_VZOOM)) MACRO_VSCROLL=(i.max-i.min)-MACRO_VZOOM;
2022-10-07 05:11:45 -04:00
}
2023-08-16 01:43:15 -04:00
ImGuiID scrollbarID=ImGui::GetID("##IMacroVScroll");
ImGui::KeepAliveID(scrollbarID);
if (ImGui::ScrollbarEx(scrollbarPos,scrollbarID,ImGuiAxis_Y,&scrollV,availV,contentsV,0)) {
MACRO_VSCROLL=(i.max-i.min-MACRO_VZOOM)-scrollV;
2022-10-07 05:11:45 -04:00
}
2022-05-07 00:52:26 -04:00
}
}
2022-10-07 17:47:18 -04:00
// bit 30 area
if (i.bit30) {
PlotCustom("##IMacroBit30",bit30Indicator,totalFit,macroDragScroll,NULL,0,1,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,&macroHoverBit30);
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
ImGui::InhibitInertialScroll();
2022-10-07 05:11:45 -04:00
macroDragStart=ImGui::GetItemRectMin();
macroDragAreaSize=ImVec2(availableWidth,12.0f*dpiScale);
2022-10-07 05:11:45 -04:00
macroDragInitialValueSet=false;
macroDragInitialValue=false;
macroDragLen=totalFit;
macroDragActive=true;
macroDragBit30=i.bit30;
macroDragSettingBit30=true;
2022-10-07 05:11:45 -04:00
macroDragTarget=i.macro->val;
macroDragChar=false;
macroDragLineMode=false;
2022-10-07 05:11:45 -04:00
macroDragLineInitial=ImVec2(0,0);
lastMacroDesc=i;
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
2022-08-22 04:52:32 -04:00
}
}
2022-10-07 05:11:45 -04:00
// loop area
PlotCustom("##IMacroLoop",loopIndicator,totalFit,macroDragScroll,NULL,0,2,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,&macroHoverLoop);
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
ImGui::InhibitInertialScroll();
macroLoopDragStart=ImGui::GetItemRectMin();
macroLoopDragAreaSize=ImVec2(availableWidth,12.0f*dpiScale);
macroLoopDragLen=totalFit;
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
macroLoopDragTarget=&i.macro->rel;
} else {
macroLoopDragTarget=&i.macro->loop;
2022-08-22 04:52:32 -04:00
}
macroLoopDragActive=true;
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
ImGui::InhibitInertialScroll();
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
i.macro->rel=255;
} else {
i.macro->loop=255;
2022-08-22 04:52:32 -04:00
}
}
ImGui::SetNextItemWidth(availableWidth);
String& mmlStr=mmlString[index];
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,i.bit30);
}
if (!ImGui::IsItemActive()) {
encodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.macro->rel,false,i.bit30);
}
}
ImGui::PopStyleVar();
} else {
if (i.macro->open&2) {
const bool compact=(availableWidth<300.0f*dpiScale);
if (ImGui::BeginTable("MacroADSR",compact?2:4)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.3);
if (!compact) {
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.3);
}
//ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch,0.4);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Bottom"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##MABottom",&i.macro->val[0],1,16)) { PARAMETER
if (i.macro->val[0]<i.min) i.macro->val[0]=i.min;
if (i.macro->val[0]>i.max) i.macro->val[0]=i.max;
2022-08-22 04:52:32 -04:00
}
2022-10-07 05:11:45 -04:00
if (compact) ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Top"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##MATop",&i.macro->val[1],1,16)) { PARAMETER
if (i.macro->val[1]<i.min) i.macro->val[1]=i.min;
if (i.macro->val[1]>i.max) i.macro->val[1]=i.max;
2022-05-07 00:52:26 -04:00
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Attack"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MAAR",&i.macro->val[2],0,255)) { PARAMETER
if (i.macro->val[2]<0) i.macro->val[2]=0;
if (i.macro->val[2]>255) i.macro->val[2]=255;
} rightClickable
2022-02-17 13:08:17 -05:00
if (compact) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Hold"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MAHT",&i.macro->val[3],0,255)) { PARAMETER
if (i.macro->val[3]<0) i.macro->val[3]=0;
if (i.macro->val[3]>255) i.macro->val[3]=255;
} rightClickable
2022-10-07 05:11:45 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Decay"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MADR",&i.macro->val[4],0,255)) { PARAMETER
if (i.macro->val[4]<0) i.macro->val[4]=0;
if (i.macro->val[4]>255) i.macro->val[4]=255;
} rightClickable
2022-10-07 05:11:45 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Sustain"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MASL",&i.macro->val[5],0,255)) { PARAMETER
if (i.macro->val[5]<0) i.macro->val[5]=0;
if (i.macro->val[5]>255) i.macro->val[5]=255;
} rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("SusTime"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MAST",&i.macro->val[6],0,255)) { PARAMETER
if (i.macro->val[6]<0) i.macro->val[6]=0;
if (i.macro->val[6]>255) i.macro->val[6]=255;
} rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("SusDecay"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MASR",&i.macro->val[7],0,255)) { PARAMETER
if (i.macro->val[7]<0) i.macro->val[7]=0;
if (i.macro->val[7]>255) i.macro->val[7]=255;
} rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Release"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MARR",&i.macro->val[8],0,255)) { PARAMETER
if (i.macro->val[8]<0) i.macro->val[8]=0;
if (i.macro->val[8]>255) i.macro->val[8]=255;
} rightClickable
} else {
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Sustain"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MASL",&i.macro->val[5],0,255)) { PARAMETER
if (i.macro->val[5]<0) i.macro->val[5]=0;
if (i.macro->val[5]>255) i.macro->val[5]=255;
} rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Hold"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MAHT",&i.macro->val[3],0,255)) { PARAMETER
if (i.macro->val[3]<0) i.macro->val[3]=0;
if (i.macro->val[3]>255) i.macro->val[3]=255;
} rightClickable
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("SusTime"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MAST",&i.macro->val[6],0,255)) { PARAMETER
if (i.macro->val[6]<0) i.macro->val[6]=0;
if (i.macro->val[6]>255) i.macro->val[6]=255;
} rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Decay"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MADR",&i.macro->val[4],0,255)) { PARAMETER
if (i.macro->val[4]<0) i.macro->val[4]=0;
if (i.macro->val[4]>255) i.macro->val[4]=255;
} rightClickable
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("SusDecay"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MASR",&i.macro->val[7],0,255)) { PARAMETER
if (i.macro->val[7]<0) i.macro->val[7]=0;
if (i.macro->val[7]>255) i.macro->val[7]=255;
} rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableNextColumn();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Release"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MARR",&i.macro->val[8],0,255)) { PARAMETER
if (i.macro->val[8]<0) i.macro->val[8]=0;
if (i.macro->val[8]>255) i.macro->val[8]=255;
} rightClickable
}
ImGui::EndTable();
}
}
if (i.macro->open&4) {
const bool compact=(availableWidth<300.0f*dpiScale);
if (ImGui::BeginTable("MacroLFO",compact?2:4)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.3);
if (!compact) {
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.3);
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Bottom"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##MABottom",&i.macro->val[0],1,16)) { PARAMETER
if (i.macro->val[0]<i.min) i.macro->val[0]=i.min;
if (i.macro->val[0]>i.max) i.macro->val[0]=i.max;
}
if (compact) ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Top"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##MATop",&i.macro->val[1],1,16)) { PARAMETER
if (i.macro->val[1]<i.min) i.macro->val[1]=i.min;
if (i.macro->val[1]>i.max) i.macro->val[1]=i.max;
2022-10-07 05:11:45 -04:00
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Speed"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MLSpeed",&i.macro->val[11],0,255)) { PARAMETER
if (i.macro->val[11]<0) i.macro->val[11]=0;
if (i.macro->val[11]>255) i.macro->val[11]=255;
} rightClickable
2022-10-07 16:06:04 -04:00
if (compact) ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Phase"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MLPhase",&i.macro->val[13],0,1023)) { PARAMETER
if (i.macro->val[13]<0) i.macro->val[13]=0;
if (i.macro->val[13]>1023) i.macro->val[13]=1023;
} rightClickable
2022-10-07 05:11:45 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Shape"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##MLShape",&i.macro->val[12],0,2,macroLFOShapes[i.macro->val[12]&3])) { PARAMETER
if (i.macro->val[12]<0) i.macro->val[12]=0;
if (i.macro->val[12]>2) i.macro->val[12]=2;
} rightClickable
2022-10-07 05:11:45 -04:00
ImGui::EndTable();
}
}
}
}
#define BUTTON_TO_SET_MODE(buttonType) \
if (buttonType(macroTypeLabels[(i.macro->open>>1)&3])) { \
unsigned char prevOpen=i.macro->open; \
if (i.macro->open>=4) { \
i.macro->open&=(~6); \
} else { \
i.macro->open+=2; \
} \
\
/* check whether macro type is now ADSR/LFO or sequence */ \
if (((prevOpen&6)?1:0)!=((i.macro->open&6)?1:0)) { \
/* swap memory */ \
/* this way the macro isn't corrupted if the user decides to go */ \
/* back to sequence mode */ \
i.macro->len^=i.ins->temp.lenMemory[i.macro->macroType]; \
i.ins->temp.lenMemory[i.macro->macroType]^=i.macro->len; \
i.macro->len^=i.ins->temp.lenMemory[i.macro->macroType]; \
\
for (int j=0; j<16; j++) { \
i.macro->val[j]^=i.ins->temp.typeMemory[i.macro->macroType][j]; \
i.ins->temp.typeMemory[i.macro->macroType][j]^=i.macro->val[j]; \
i.macro->val[j]^=i.ins->temp.typeMemory[i.macro->macroType][j]; \
} \
\
/* if ADSR/LFO, populate min/max */ \
if (i.macro->open&6) { \
2023-08-24 05:31:32 -04:00
if (i.macro->val[0]==0 && i.macro->val[1]==0) { \
i.macro->val[0]=i.min; \
i.macro->val[1]=i.max; \
} \
2023-08-24 05:31:32 -04:00
i.macro->val[0]=CLAMP(i.macro->val[0],i.min,i.max); \
i.macro->val[1]=CLAMP(i.macro->val[1],i.min,i.max); \
} \
} \
PARAMETER; \
} \
if (ImGui::IsItemHovered()) { \
switch (i.macro->open&6) { \
case 0: \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Macro type: Sequence")); \
break; \
case 2: \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Macro type: ADSR")); \
break; \
case 4: \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Macro type: LFO")); \
break; \
default: \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Macro type: What's going on here?")); \
break; \
} \
} \
if (i.macro->open&6) { \
i.macro->len=16; \
}
2022-11-11 00:46:39 -05:00
#define BUTTON_TO_SET_PROPS(_x) \
pushToggleColors(_x.macro->speed!=1 || _x.macro->delay); \
ImGui::Button(ICON_FA_ELLIPSIS_H "##IMacroSet"); \
popToggleColors(); \
if (ImGui::IsItemHovered()) { \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Delay/Step Length")); \
} \
if (ImGui::BeginPopupContextItem("IMacroSetP",ImGuiPopupFlags_MouseButtonLeft)) { \
2024-05-26 20:31:17 -04:00
if (ImGui::InputScalar(_("Step Length (ticks)##IMacroSpeed"),ImGuiDataType_U8,&_x.macro->speed,&_ONE,&_THREE)) { \
2022-11-11 00:46:39 -05:00
if (_x.macro->speed<1) _x.macro->speed=1; \
MARK_MODIFIED; \
} \
2024-05-26 20:31:17 -04:00
if (ImGui::InputScalar(_("Delay##IMacroDelay"),ImGuiDataType_U8,&_x.macro->delay,&_ONE,&_THREE)) { \
MARK_MODIFIED; \
} \
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) { \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Release mode: Active (jump to release pos)")); \
} else { \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Release mode: Passive (delayed release)")); \
} \
} \
popToggleColors(); \
2025-03-10 13:46:46 -04:00
void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUIMacroEditState& state, DivInstrument* ins) {
int index=0;
int maxMacroLen=0;
float reservedSpace=(settings.oldMacroVSlider)?(20.0f*dpiScale+ImGui::GetStyle().ItemSpacing.x):ImGui::GetStyle().ScrollbarSize;
for (FurnaceGUIMacroDesc& m: macros) {
2025-03-10 13:46:46 -04:00
m.ins=ins;
if (m.macro->len>maxMacroLen) maxMacroLen=m.macro->len;
}
switch (settings.macroLayout) {
case 0: {
if (ImGui::BeginTable("MacroSpace",2)) {
2024-06-24 15:56:47 -04:00
float precalcWidth=0.0f;
for (FurnaceGUIMacroDesc& i: macros) {
float next=ImGui::CalcTextSize(i.displayName).x+ImGui::GetStyle().ItemInnerSpacing.x*2.0f+ImGui::CalcTextSize(ICON_FA_CHEVRON_UP).x+ImGui::GetStyle().ItemSpacing.x*2.0f;
if (next>precalcWidth) precalcWidth=next;
}
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,MAX(120.0f*dpiScale,precalcWidth));
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableNextRow();
ImGui::TableNextColumn();
float lenAvail=ImGui::GetContentRegionAvail().x;
//ImGui::Dummy(ImVec2(120.0f*dpiScale,dpiScale));
if (settings.autoMacroStepSize==0) {
2024-07-25 14:18:22 -04:00
ImGui::SetNextItemWidth(120.0f*dpiScale);
if (ImGui::InputInt("##MacroPointSize",&macroPointSize,1,4)) {
if (macroPointSize<1) macroPointSize=1;
if (macroPointSize>256) macroPointSize=256;
}
}
ImGui::TableNextColumn();
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
int totalFit=MIN(255,availableWidth/MAX(1,macroPointSize*dpiScale));
int scrollMax=0;
if (settings.autoMacroStepSize!=0) totalFit=1;
for (FurnaceGUIMacroDesc& i: macros) {
if (i.macro->len>scrollMax) scrollMax=i.macro->len;
if (settings.autoMacroStepSize==1) {
2024-07-25 14:18:22 -04:00
if ((i.macro->open&6)==0 && totalFit<i.macro->len) totalFit=i.macro->len;
} else if (settings.autoMacroStepSize==2) {
if ((i.macro->open&6)==0 && totalFit<maxMacroLen) totalFit=maxMacroLen;
2024-07-25 14:18:22 -04:00
}
}
scrollMax-=totalFit;
if (scrollMax<0) scrollMax=0;
if (macroDragScroll>scrollMax) {
macroDragScroll=scrollMax;
}
ImGui::BeginDisabled(scrollMax<1);
ImGui::SetNextItemWidth(availableWidth);
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,scrollMax,"")) {
if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll>scrollMax) macroDragScroll=scrollMax;
}
ImGui::EndDisabled();
// draw macros
for (FurnaceGUIMacroDesc& i: macros) {
ImGui::PushID(index);
ImGui::TableNextRow();
2022-10-07 05:11:45 -04:00
// description
ImGui::TableNextColumn();
ImGui::Text("%s",i.displayName);
ImGui::SameLine();
if (ImGui::SmallButton((i.macro->open&1)?(ICON_FA_CHEVRON_UP "##IMacroOpen"):(ICON_FA_CHEVRON_DOWN "##IMacroOpen"))) {
i.macro->open^=1;
}
if (i.macro->open&1) {
if ((i.macro->open&6)==0) {
ImGui::SetNextItemWidth(lenAvail);
int macroLen=i.macro->len;
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;
}
2022-10-07 05:11:45 -04:00
}
BUTTON_TO_SET_MODE(ImGui::Button);
ImGui::SameLine();
2022-11-11 00:46:39 -05:00
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.
if (i.modeName!=NULL) {
bool modeVal=i.macro->mode;
String modeName=fmt::sprintf("%s##IMacroMode",i.modeName);
if (ImGui::Checkbox(modeName.c_str(),&modeVal)) {
i.macro->mode=modeVal;
}
}
2022-10-07 16:06:04 -04:00
}
2022-10-07 05:11:45 -04:00
// macro area
ImGui::TableNextColumn();
drawMacroEdit(i,totalFit,availableWidth,index);
ImGui::PopID();
index++;
}
2022-10-07 05:11:45 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableNextColumn();
ImGui::BeginDisabled(scrollMax<1);
ImGui::SetNextItemWidth(availableWidth);
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,scrollMax,"")) {
if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll>scrollMax) macroDragScroll=scrollMax;
2022-05-07 00:52:26 -04:00
}
ImGui::EndDisabled();
ImGui::EndTable();
2022-05-07 00:52:26 -04:00
}
break;
2022-05-07 00:52:26 -04:00
}
case 1: {
2023-08-16 01:43:15 -04:00
ImGui::Text("Tabs");
break;
}
case 2: {
2022-11-11 00:46:39 -05:00
int columns=round(ImGui::GetContentRegionAvail().x/(400.0*dpiScale));
int curColumn=0;
2023-01-04 22:59:21 -05:00
if (columns<1) columns=1;
2022-11-11 00:46:39 -05:00
if (ImGui::BeginTable("MacroGrid",columns,ImGuiTableFlags_BordersInner)) {
for (FurnaceGUIMacroDesc& i: macros) {
if (curColumn==0) ImGui::TableNextRow();
ImGui::TableNextColumn();
2022-11-11 00:46:39 -05:00
if (++curColumn>=columns) curColumn=0;
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
int totalFit=i.macro->len;
if (totalFit<1) totalFit=1;
2022-10-07 05:11:45 -04:00
2022-11-11 00:46:39 -05:00
ImGui::PushID(index);
2022-10-07 05:11:45 -04:00
2022-11-11 00:46:39 -05:00
ImGui::TextUnformatted(i.displayName);
ImGui::SameLine();
2022-11-11 00:46:39 -05:00
if (ImGui::SmallButton((i.macro->open&1)?(ICON_FA_CHEVRON_UP "##IMacroOpen"):(ICON_FA_CHEVRON_DOWN "##IMacroOpen"))) {
i.macro->open^=1;
}
2022-10-07 05:11:45 -04:00
2022-11-11 00:46:39 -05:00
if (i.macro->open&1) {
ImGui::SameLine();
2022-11-11 00:46:39 -05:00
BUTTON_TO_SET_MODE(ImGui::SmallButton);
}
2022-10-07 05:11:45 -04:00
2022-11-11 00:46:39 -05:00
drawMacroEdit(i,totalFit,availableWidth,index);
2022-10-07 05:11:45 -04:00
2022-11-11 00:46:39 -05:00
if (i.macro->open&1) {
if ((i.macro->open&6)==0) {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Length"));
2022-11-11 00:46:39 -05:00
ImGui::SameLine();
ImGui::SetNextItemWidth(120.0f*dpiScale);
int macroLen=i.macro->len;
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;
}
ImGui::SameLine();
2022-10-07 05:11:45 -04:00
}
2022-11-11 00:46:39 -05:00
BUTTON_TO_SET_PROPS(i);
if ((i.macro->open&6)==0) {
ImGui::SameLine();
BUTTON_TO_SET_RELEASE(ImGui::Button);
}
2022-11-11 00:46:39 -05:00
if (i.modeName!=NULL) {
bool modeVal=i.macro->mode;
String modeName=fmt::sprintf("%s##IMacroMode",i.modeName);
ImGui::SameLine();
if (ImGui::Checkbox(modeName.c_str(),&modeVal)) {
i.macro->mode=modeVal;
}
2022-10-07 05:11:45 -04:00
}
}
2022-10-07 05:11:45 -04:00
2022-11-11 00:46:39 -05:00
ImGui::PopID();
index++;
}
ImGui::EndTable();
}
break;
}
case 3: {
2022-11-11 00:46:39 -05:00
if (ImGui::BeginTable("MacroList",2,ImGuiTableFlags_Borders)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.2f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.8f);
2022-11-11 00:46:39 -05:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
for (size_t i=0; i<macros.size(); i++) {
// include macro len if non-zero, making particularly clear at-a-glance which macros
// have non-zero len (i.e. are active). and calculate how big we need to be to leave some
// extra space so the column doesn't change size when len is changed under typical
// circumstances (really don't want to move buttons while mouse is being clicked or held).
char buf[256];
if (macros[i].macro->len>0) {
snprintf(buf,255,"%s [%d]###%s",macros[i].displayName,macros[i].macro->len,macros[i].displayName);
} else {
snprintf(buf,255,"%s",macros[i].displayName);
}
if (ImGui::Selectable(buf,state.selectedMacro==(int)i)) {
2022-11-11 00:46:39 -05:00
state.selectedMacro=i;
2022-05-07 00:52:26 -04:00
}
}
2022-10-07 16:06:04 -04:00
2022-11-11 00:46:39 -05:00
ImGui::TableNextColumn();
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
int totalFit=MIN(255,availableWidth/MAX(1,macroPointSize*dpiScale));
if (macroDragScroll>255-totalFit) {
macroDragScroll=255-totalFit;
}
2022-10-07 16:06:04 -04:00
2022-11-11 00:46:39 -05:00
if (state.selectedMacro<0 || state.selectedMacro>=(int)macros.size()) {
state.selectedMacro=0;
}
2022-10-07 16:06:04 -04:00
2022-11-11 00:46:39 -05:00
if (state.selectedMacro>=0 && state.selectedMacro<(int)macros.size()) {
FurnaceGUIMacroDesc& m=macros[state.selectedMacro];
m.macro->open|=1;
2022-10-07 16:06:04 -04:00
2023-08-16 01:43:15 -04:00
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
int totalFit=MIN(255,availableWidth/MAX(1,macroPointSize*dpiScale));
int scrollMax=0;
for (FurnaceGUIMacroDesc& i: macros) {
if (i.macro->len>scrollMax) scrollMax=i.macro->len;
}
if (settings.autoMacroStepSize==1) totalFit=MAX(1,m.macro->len);
else if (settings.autoMacroStepSize==2) totalFit=MAX(1,maxMacroLen);
2023-08-16 01:43:15 -04:00
scrollMax-=totalFit;
if (scrollMax<0) scrollMax=0;
if (macroDragScroll>scrollMax) {
macroDragScroll=scrollMax;
}
ImGui::BeginDisabled(scrollMax<1);
ImGui::SetNextItemWidth(availableWidth);
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,scrollMax,"")) {
if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll>scrollMax) macroDragScroll=scrollMax;
}
ImGui::EndDisabled();
if (settings.autoMacroStepSize==0) {
2024-07-25 14:18:22 -04:00
ImGui::SameLine();
ImGui::Button(ICON_FA_SEARCH_PLUS "##MacroZoomB");
if (ImGui::BeginPopupContextItem("MacroZoomP",ImGuiPopupFlags_MouseButtonLeft)) {
ImGui::SetNextItemWidth(120.0f*dpiScale);
if (ImGui::InputInt("##MacroPointSize",&macroPointSize,1,4)) {
if (macroPointSize<1) macroPointSize=1;
if (macroPointSize>256) macroPointSize=256;
}
ImGui::EndPopup();
2023-08-16 01:43:15 -04:00
}
}
m.height=ImGui::GetContentRegionAvail().y-ImGui::GetFontSize()-ImGui::GetFrameHeightWithSpacing()-(m.bit30?28.0f:12.0f)*dpiScale-ImGui::GetStyle().ItemSpacing.y*3.0f;
2022-11-11 00:46:39 -05:00
if (m.height<10.0f*dpiScale) m.height=10.0f*dpiScale;
m.height/=dpiScale;
drawMacroEdit(m,totalFit,availableWidth,index);
2022-10-07 16:06:04 -04:00
2022-11-11 00:46:39 -05:00
if (m.macro->open&1) {
bool showLen=((m.macro->open&6)==0);
int colCount=showLen ? 4 : 3;
float availX=ImGui::GetContentRegionAvail().x;
// fairly arbitrary scaling logic
bool shortLabels=(availX<600.0f*dpiScale);
2024-09-12 01:11:51 -04:00
float scalarItemWidth=MIN((availX-90.0f*dpiScale)/colCount, 120.0f*dpiScale);
if (ImGui::BeginTable("##MacroMetaData",colCount)) {
if (showLen) ImGui::TableSetupColumn("len",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("stepLen",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("delay",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("buttons",ImGuiTableColumnFlags_WidthFixed,0.0);
ImGui::TableNextRow();
if (showLen) {
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(shortLabels ? _("Len##macroEditLengthShortLabel") : _("Length"));
if (shortLabels && ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _("Length"));
ImGui::SameLine();
ImGui::SetNextItemWidth(scalarItemWidth);
int macroLen=m.macro->len;
if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,&macroLen,&_ONE,&_THREE)) { MARK_MODIFIED
if (macroLen<0) macroLen=0;
if (macroLen>255) macroLen=255;
m.macro->len=macroLen;
}
2022-11-11 00:46:39 -05:00
}
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(shortLabels ? _("SLen##macroEditStepLenShortLabel") : _("StepLen"));
if (shortLabels && ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _("StepLen"));
2022-11-11 00:46:39 -05:00
ImGui::SameLine();
ImGui::SetNextItemWidth(scalarItemWidth);
if (ImGui::InputScalar("##IMacroSpeed",ImGuiDataType_U8,&m.macro->speed,&_ONE,&_THREE)) {
if (m.macro->speed<1) m.macro->speed=1;
MARK_MODIFIED;
}
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(shortLabels ? _("Del##macroEditDelayShortLabel") : _("Delay"));
if (shortLabels && ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _("Delay"));
2022-11-11 00:46:39 -05:00
ImGui::SameLine();
ImGui::SetNextItemWidth(scalarItemWidth);
if (ImGui::InputScalar("##IMacroDelay",ImGuiDataType_U8,&m.macro->delay,&_ONE,&_THREE)) {
MARK_MODIFIED;
2022-11-11 00:46:39 -05:00
}
ImGui::TableNextColumn();
{
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;
String modeName=fmt::sprintf("%s##IMacroMode",m.modeName);
ImGui::SameLine();
if (ImGui::Checkbox(modeName.c_str(),&modeVal)) {
m.macro->mode=modeVal;
}
2022-11-11 00:46:39 -05:00
}
ImGui::EndTable();
2022-10-07 16:06:04 -04:00
}
2022-11-11 00:46:39 -05:00
} else {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("The heck? No, this isn't even working correctly..."));
2022-05-07 00:52:26 -04:00
}
2022-11-11 00:46:39 -05:00
} else {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("The only problem with that selectedMacro is that it's a bug..."));
2022-05-07 00:52:26 -04:00
}
2022-11-11 00:46:39 -05:00
// goes here
ImGui::EndTable();
2022-05-07 00:52:26 -04:00
}
break;
2022-05-07 00:52:26 -04:00
}
case 4: {
ImGui::Text("Single (combo box)");
break;
2022-05-07 00:52:26 -04:00
}
}
2022-02-17 13:08:17 -05:00
}
void FurnaceGUI::alterSampleMap(int column, int val) {
if (curIns<0 || curIns>=(int)e->song.ins.size()) return;
DivInstrument* ins=e->song.ins[curIns];
int sampleMapMin=sampleMapSelStart;
int sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
for (int i=sampleMapMin; i<=sampleMapMax; i++) {
if (i<0 || i>=120) continue;
if (sampleMapColumn==1 && column==1) {
ins->amiga.noteMap[i].freq=val;
} else if (sampleMapColumn==0 && column==0) {
if (val<0) {
ins->amiga.noteMap[i].map=-1;
} else if (sampleMapDigit>0) {
ins->amiga.noteMap[i].map*=10;
ins->amiga.noteMap[i].map+=val;
} else {
ins->amiga.noteMap[i].map=val;
}
if (ins->amiga.noteMap[i].map>=(int)e->song.sample.size()) {
ins->amiga.noteMap[i].map=((int)e->song.sample.size())-1;
}
} else if (sampleMapColumn==2 && column==2) {
if (val<0) {
ins->amiga.noteMap[i].dpcmFreq=-1;
} else if (sampleMapDigit>0) {
ins->amiga.noteMap[i].dpcmFreq*=10;
ins->amiga.noteMap[i].dpcmFreq+=val;
} else {
ins->amiga.noteMap[i].dpcmFreq=val;
}
if (ins->amiga.noteMap[i].dpcmFreq>15) {
ins->amiga.noteMap[i].dpcmFreq%=10;
}
} else if (sampleMapColumn==3 && column==3) {
if (val<0) {
ins->amiga.noteMap[i].dpcmDelta=-1;
} else if (sampleMapDigit>0) {
if (ins->amiga.noteMap[i].dpcmDelta>7) {
ins->amiga.noteMap[i].dpcmDelta=val;
} else {
ins->amiga.noteMap[i].dpcmDelta<<=4;
ins->amiga.noteMap[i].dpcmDelta+=val;
}
} else {
ins->amiga.noteMap[i].dpcmDelta=val;
}
}
}
bool advance=false;
if (sampleMapColumn==1 && column==1) {
advance=true;
} else if (sampleMapColumn==0 && column==0) {
int digits=1;
if (e->song.sample.size()>=10) digits=2;
if (e->song.sample.size()>=100) digits=3;
if (++sampleMapDigit>=digits) {
sampleMapDigit=0;
advance=true;
}
} else if (sampleMapColumn==2 && column==2) {
if (++sampleMapDigit>=2) {
sampleMapDigit=0;
advance=true;
}
} else if (sampleMapColumn==3 && column==3) {
if (++sampleMapDigit>=2) {
sampleMapDigit=0;
advance=true;
}
}
if (advance && sampleMapMin==sampleMapMax) {
sampleMapSelStart++;
if (sampleMapSelStart>119) sampleMapSelStart=119;
sampleMapSelEnd=sampleMapSelStart;
}
MARK_MODIFIED;
}
2022-03-17 03:07:46 -04:00
#define DRUM_FREQ(name,db,df,prop) \
ImGui::TableNextRow(); \
ImGui::TableNextColumn(); \
if (ins->type==DIV_INS_OPLL) { \
block=(prop>>9)&7; \
fNum=prop&511; \
} else { \
block=(prop>>10)&7; \
fNum=prop&1023; \
} \
ImGui::Text(name); \
ImGui::TableNextColumn(); \
if (ImGui::InputInt(db,&block,1,1)) { \
if (block<0) block=0; \
if (block>7) block=7; \
if (ins->type==DIV_INS_OPLL) { \
prop=(block<<9)|fNum; \
} else { \
prop=(block<<10)|fNum; \
} \
} \
ImGui::TableNextColumn(); \
if (ImGui::InputInt(df,&fNum,1,16)) { \
2022-03-17 03:07:46 -04:00
if (fNum<0) fNum=0; \
if (ins->type==DIV_INS_OPLL) { \
if (fNum>511) fNum=511; \
prop=(block<<9)|fNum; \
} else { \
if (fNum>1023) fNum=1023; \
prop=(block<<10)|fNum; \
} \
}
2022-03-27 02:38:24 -04:00
#define CENTER_TEXT(text) \
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+0.5*(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(text).x));
#define CENTER_VSLIDER \
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+0.5f*ImGui::GetContentRegionAvail().x-10.0f*dpiScale);
2022-03-27 02:38:24 -04:00
2022-06-13 04:54:42 -04:00
#define CENTER_TEXT_20(text) \
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+0.5*(20.0f*dpiScale-ImGui::CalcTextSize(text).x));
#define TOOLTIP_TEXT(text) \
if (ImGui::IsItemHovered()) { \
ImGui::SetTooltip("%s", text); \
}
2022-09-11 00:20:22 -04:00
#define OP_DRAG_POINT \
if (ImGui::Button(ICON_FA_ARROWS)) { \
} \
if (ImGui::BeginDragDropSource()) { \
opToMove=i; \
ImGui::SetDragDropPayload("FUR_OP",NULL,0,ImGuiCond_Once); \
ImGui::Button(ICON_FA_ARROWS "##SysDrag"); \
2022-09-13 04:29:28 -04:00
ImGui::SameLine(); \
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { \
2024-05-26 20:31:17 -04:00
ImGui::Text(_("(copying)")); \
2022-09-13 04:29:28 -04:00
} else { \
2024-05-26 20:31:17 -04:00
ImGui::Text(_("(swapping)")); \
2022-09-13 04:29:28 -04:00
} \
2022-09-11 00:20:22 -04:00
ImGui::EndDragDropSource(); \
} else if (ImGui::IsItemHovered()) { \
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("- drag to swap operator\n- shift-drag to copy operator")); \
2022-09-11 00:20:22 -04:00
} \
if (ImGui::BeginDragDropTarget()) { \
const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_OP"); \
if (dragItem!=NULL) { \
if (dragItem->IsDataType("FUR_OP")) { \
if (opToMove!=i && opToMove>=0) { \
int destOp=(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i; \
int sourceOp=(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[opToMove]:opToMove; \
2022-09-13 04:29:28 -04:00
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { \
2022-09-16 01:04:43 -04:00
e->lockEngine([ins,destOp,sourceOp]() { \
ins->fm.op[destOp]=ins->fm.op[sourceOp]; \
ins->esfm.op[destOp]=ins->esfm.op[sourceOp]; \
2022-09-13 04:29:28 -04:00
}); \
} else { \
2022-09-16 01:04:43 -04:00
e->lockEngine([ins,destOp,sourceOp]() { \
DivInstrumentFM::Operator origOp=ins->fm.op[sourceOp]; \
DivInstrumentESFM::Operator origOpE=ins->esfm.op[sourceOp]; \
2022-09-16 01:04:43 -04:00
ins->fm.op[sourceOp]=ins->fm.op[destOp]; \
ins->esfm.op[sourceOp]=ins->esfm.op[destOp]; \
2022-09-16 01:04:43 -04:00
ins->fm.op[destOp]=origOp; \
ins->esfm.op[destOp]=origOpE; \
2022-09-13 04:29:28 -04:00
}); \
} \
2022-09-11 00:20:22 -04:00
PARAMETER; \
} \
opToMove=-1; \
} \
} \
ImGui::EndDragDropTarget(); \
}
void FurnaceGUI::insTabWavetable(DivInstrument* ins)
{
if (ImGui::BeginTabItem(_("Wavetable"))) {
switch (ins->type) {
case DIV_INS_GB:
case DIV_INS_NAMCO:
case DIV_INS_SM8521:
case DIV_INS_SWAN:
wavePreviewLen=32;
wavePreviewHeight=15;
break;
case DIV_INS_PCE:
wavePreviewLen=32;
wavePreviewHeight=31;
break;
case DIV_INS_VBOY:
wavePreviewLen=32;
wavePreviewHeight=63;
break;
case DIV_INS_SCC:
wavePreviewLen=32;
wavePreviewHeight=255;
break;
case DIV_INS_FDS:
wavePreviewLen=64;
wavePreviewHeight=63;
break;
case DIV_INS_N163:
wavePreviewLen=ins->n163.waveLen;
wavePreviewHeight=15;
break;
case DIV_INS_X1_010:
wavePreviewLen=128;
wavePreviewHeight=255;
break;
case DIV_INS_AMIGA:
case DIV_INS_GBA_DMA:
wavePreviewLen=ins->amiga.waveLen+1;
wavePreviewHeight=255;
break;
case DIV_INS_SNES:
wavePreviewLen=ins->amiga.waveLen+1;
wavePreviewHeight=15;
break;
case DIV_INS_GBA_MINMOD:
wavePreviewLen=ins->amiga.waveLen+1;
wavePreviewHeight=255;
break;
case DIV_INS_SID3:
wavePreviewLen=256;
wavePreviewHeight=255;
break;
default:
wavePreviewLen=32;
wavePreviewHeight=31;
break;
}
if (ImGui::Checkbox(_("Enable synthesizer"),&ins->ws.enabled)) { PARAMETER
wavePreviewInit=true;
}
if (ins->ws.enabled) {
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ins->ws.effect&0x80) {
if ((ins->ws.effect&0x7f)>=DIV_WS_DUAL_MAX) {
ins->ws.effect=0;
wavePreviewInit=true;
}
} else {
if ((ins->ws.effect&0x7f)>=DIV_WS_SINGLE_MAX) {
ins->ws.effect=0;
wavePreviewInit=true;
}
}
if (ImGui::BeginCombo("##WSEffect",(ins->ws.effect&0x80)?dualWSEffects[ins->ws.effect&0x7f]:singleWSEffects[ins->ws.effect&0x7f])) {
ImGui::Text(_("Single-waveform"));
ImGui::Indent();
for (int i=0; i<DIV_WS_SINGLE_MAX; i++) {
if (ImGui::Selectable(_(singleWSEffects[i]))) { PARAMETER
ins->ws.effect=i;
wavePreviewInit=true;
}
}
ImGui::Unindent();
ImGui::Text(_("Dual-waveform"));
ImGui::Indent();
for (int i=129; i<DIV_WS_DUAL_MAX; i++) {
if (ImGui::Selectable(_(dualWSEffects[i-128]))) { PARAMETER
ins->ws.effect=i;
wavePreviewInit=true;
}
}
ImGui::Unindent();
ImGui::EndCombo();
}
const bool isSingleWaveFX=(ins->ws.effect>=128);
if (ImGui::BeginTable("WSPreview",isSingleWaveFX?3:2)) {
DivWavetable* wave1=e->getWave(ins->ws.wave1);
DivWavetable* wave2=e->getWave(ins->ws.wave2);
if (wavePreviewInit) {
wavePreview.init(ins,wavePreviewLen,wavePreviewHeight,true);
wavePreviewInit=false;
}
float wavePreview1[257];
float wavePreview2[257];
float wavePreview3[257];
for (int i=0; i<wave1->len; i++) {
if (wave1->data[i]>wave1->max) {
wavePreview1[i]=wave1->max;
} else {
wavePreview1[i]=wave1->data[i];
}
}
if (wave1->len>0) {
wavePreview1[wave1->len]=wave1->data[wave1->len-1];
}
for (int i=0; i<wave2->len; i++) {
if (wave2->data[i]>wave2->max) {
wavePreview2[i]=wave2->max;
} else {
wavePreview2[i]=wave2->data[i];
}
}
if (wave2->len>0) {
wavePreview2[wave2->len]=wave2->data[wave2->len-1];
}
if (ins->ws.enabled && (!wavePreviewPaused || wavePreviewInit)) {
wavePreview.tick(true);
WAKE_UP;
}
for (int i=0; i<wavePreviewLen; i++) {
wavePreview3[i]=wavePreview.output[i];
}
if (wavePreviewLen>0) {
wavePreview3[wavePreviewLen]=wavePreview3[wavePreviewLen-1];
}
float ySize=(isSingleWaveFX?96.0f:128.0f)*dpiScale;
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImVec2 size1=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
PlotNoLerp("##WaveformP1",wavePreview1,wave1->len+1,0,"Wave 1",0,wave1->max,size1);
if (isSingleWaveFX) {
ImGui::TableNextColumn();
ImVec2 size2=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
PlotNoLerp("##WaveformP2",wavePreview2,wave2->len+1,0,"Wave 2",0,wave2->max,size2);
}
ImGui::TableNextColumn();
ImVec2 size3=ImVec2(ImGui::GetContentRegionAvail().x,ySize);
PlotNoLerp("##WaveformP3",wavePreview3,wavePreviewLen+1,0,"Result",0,wavePreviewHeight,size3);
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ins->std.waveMacro.len>0) {
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_WARNING]);
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Wave 1"));
ImGui::SameLine();
ImGui::Text(ICON_FA_EXCLAMATION_TRIANGLE);
ImGui::PopStyleColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("waveform macro is controlling wave 1!\nthis value will be ineffective."));
}
} else {
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Wave 1"));
}
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##SelWave1",&ins->ws.wave1,1,4)) { PARAMETER
if (ins->ws.wave1<0) ins->ws.wave1=0;
if (ins->ws.wave1>=(int)e->song.wave.size()) ins->ws.wave1=e->song.wave.size()-1;
wavePreviewInit=true;
}
if (ins->std.waveMacro.len>0) {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("waveform macro is controlling wave 1!\nthis value will be ineffective."));
}
}
if (isSingleWaveFX) {
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Wave 2"));
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##SelWave2",&ins->ws.wave2,1,4)) { PARAMETER
if (ins->ws.wave2<0) ins->ws.wave2=0;
if (ins->ws.wave2>=(int)e->song.wave.size()) ins->ws.wave2=e->song.wave.size()-1;
wavePreviewInit=true;
}
}
ImGui::TableNextColumn();
if (ImGui::Button(wavePreviewPaused?(ICON_FA_PLAY "##WSPause"):(ICON_FA_PAUSE "##WSPause"))) {
wavePreviewPaused=!wavePreviewPaused;
}
if (ImGui::IsItemHovered()) {
if (wavePreviewPaused) {
ImGui::SetTooltip(_("Resume preview"));
} else {
ImGui::SetTooltip(_("Pause preview"));
}
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_REPEAT "##WSRestart")) {
wavePreviewInit=true;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Restart preview"));
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_UPLOAD "##WSCopy")) {
curWave=e->addWave();
if (curWave==-1) {
showError(_("too many wavetables!"));
} else {
wantScrollListWave=true;
MARK_MODIFIED;
RESET_WAVE_MACRO_ZOOM;
nextWindow=GUI_WINDOW_WAVE_EDIT;
DivWavetable* copyWave=e->song.wave[curWave];
copyWave->len=wavePreviewLen;
copyWave->max=wavePreviewHeight;
memcpy(copyWave->data,wavePreview.output,256*sizeof(int));
}
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Copy to new wavetable"));
}
ImGui::SameLine();
ImGui::Text("(%d×%d)",wavePreviewLen,wavePreviewHeight+1);
ImGui::EndTable();
}
if (ImGui::InputScalar(_("Update Rate"),ImGuiDataType_U8,&ins->ws.rateDivider,&_ONE,&_EIGHT)) { PARAMETER
wavePreviewInit=true;
}
int speed=ins->ws.speed+1;
if (ImGui::InputInt(_("Speed"),&speed,1,8)) { PARAMETER
if (speed<1) speed=1;
if (speed>256) speed=256;
ins->ws.speed=speed-1;
wavePreviewInit=true;
}
if (ImGui::InputScalar(_("Amount"),ImGuiDataType_U8,&ins->ws.param1,&_ONE,&_EIGHT)) { PARAMETER
wavePreviewInit=true;
}
if (ins->ws.effect==DIV_WS_PHASE_MOD) {
if (ImGui::InputScalar(_("Power"),ImGuiDataType_U8,&ins->ws.param2,&_ONE,&_EIGHT)) { PARAMETER
wavePreviewInit=true;
}
}
if (ImGui::Checkbox(_("Global"),&ins->ws.global)) { PARAMETER
wavePreviewInit=true;
}
} else {
ImGui::TextWrapped(_("wavetable synthesizer disabled.\nuse the Waveform macro to set the wave for this instrument."));
}
ImGui::EndTabItem();
}
}
void FurnaceGUI::insTabSample(DivInstrument* ins) {
2024-05-26 20:31:17 -04:00
const char* sampleTabName=_("Sample");
if (ins->type==DIV_INS_NES) sampleTabName=_("DPCM");
if (ImGui::BeginTabItem(sampleTabName)) {
2023-10-13 20:57:36 -04:00
if (ins->type==DIV_INS_NES && e->song.oldDPCM) {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("new DPCM features disabled (compatibility)!"));
if (ImGui::Button(_("click here to enable them."))) {
2023-10-13 20:57:36 -04:00
e->song.oldDPCM=false;
MARK_MODIFIED;
}
ImGui::EndTabItem();
return;
}
String sName;
bool wannaOpenSMPopup=false;
if (ins->amiga.initSample<0 || ins->amiga.initSample>=e->song.sampleLen) {
2024-05-26 20:31:17 -04:00
sName=_("none selected");
} else {
sName=e->song.sample[ins->amiga.initSample]->name;
}
if (ins->type==DIV_INS_PCE ||
ins->type==DIV_INS_MIKEY ||
ins->type==DIV_INS_X1_010 ||
ins->type==DIV_INS_SWAN ||
ins->type==DIV_INS_AY ||
ins->type==DIV_INS_AY8930 ||
ins->type==DIV_INS_VRC6 ||
ins->type==DIV_INS_SU ||
ins->type==DIV_INS_NDS ||
2024-09-14 00:46:03 -04:00
ins->type==DIV_INS_SUPERVISION ||
ins->type==DIV_INS_SID3) {
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Use sample"),&ins->amiga.useSample));
if (ins->type==DIV_INS_X1_010) {
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Sample bank slot##BANKSLOT"),&ins->x1_010.bankSlot,1,4)) { PARAMETER
if (ins->x1_010.bankSlot<0) ins->x1_010.bankSlot=0;
if (ins->x1_010.bankSlot>=7) ins->x1_010.bankSlot=7;
}
}
}
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Sample"));
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::BeginCombo("##ISample",sName.c_str())) {
String id;
for (int i=0; i<e->song.sampleLen; i++) {
id=fmt::sprintf("%d: %s",i,e->song.sample[i]->name);
if (ImGui::Selectable(id.c_str(),ins->amiga.initSample==i)) { PARAMETER
ins->amiga.initSample=i;
}
}
ImGui::EndCombo();
}
// Wavetable
2024-03-16 03:59:02 -04:00
if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SNES || ins->type==DIV_INS_GBA_DMA || ins->type==DIV_INS_GBA_MINMOD) {
2024-05-26 20:31:17 -04:00
const char* useWaveText=ins->type==DIV_INS_AMIGA?_("Use wavetable (Amiga/Generic DAC only)"):_("Use wavetable");
ImGui::BeginDisabled(ins->amiga.useNoteMap);
2024-01-09 23:17:36 -05:00
P(ImGui::Checkbox(useWaveText,&ins->amiga.useWave));
if (ins->amiga.useWave) {
int len=ins->amiga.waveLen+1;
int origLen=len;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Width"),&len,2,16)) {
2024-01-09 23:17:36 -05:00
if (ins->type==DIV_INS_SNES || ins->type==DIV_INS_GBA_DMA) {
if (len<16) len=16;
if (len>256) len=256;
if (len>origLen) {
ins->amiga.waveLen=((len+15)&(~15))-1;
} else {
ins->amiga.waveLen=(len&(~15))-1;
}
} else {
if (len<2) len=2;
if (len>256) len=256;
ins->amiga.waveLen=(len&(~1))-1;
}
PARAMETER
}
}
ImGui::EndDisabled();
}
// Note map
ImGui::BeginDisabled(ins->amiga.useWave);
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Use sample map"),&ins->amiga.useNoteMap));
if (ins->amiga.useNoteMap) {
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) sampleMapFocused=false;
if (curWindowLast!=GUI_WINDOW_INS_EDIT) sampleMapFocused=false;
if (!sampleMapFocused) sampleMapDigit=0;
if (ImGui::BeginTable("NoteMap",(ins->type==DIV_INS_NES)?5:4,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
if (ins->type==DIV_INS_NES) ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupScrollFreeze(0,1);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::TableNextColumn();
ImGui::Text("#");
if (ins->type==DIV_INS_NES) {
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("pitch"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("delta"));
} else {
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("note"));
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("sample name"));
int sampleMapMin=sampleMapSelStart;
int sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
ImGui::PushStyleColor(ImGuiCol_Header,ImGui::GetColorU32(ImGuiCol_HeaderHovered));
ImGui::PushStyleColor(ImGuiCol_HeaderActive,ImGui::GetColorU32(ImGuiCol_HeaderHovered));
for (int i=0; i<120; i++) {
DivInstrumentAmiga::SampleMap& sampleMap=ins->amiga.noteMap[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_TableHeaderBg));
ImGui::AlignTextToFramePadding();
ImGui::Text("%s",noteNames[60+i]);
ImGui::TableNextColumn();
if (sampleMap.map<0 || sampleMap.map>=e->song.sampleLen) {
sName=fmt::sprintf("---##SM%d",i);
sampleMap.map=-1;
} else {
sName=fmt::sprintf("%3d##SM%d",sampleMap.map,i);
}
ImGui::PushFont(patFont);
ImGui::AlignTextToFramePadding();
ImGui::SetNextItemWidth(ImGui::CalcTextSize("00000").x);
ImGui::Selectable(sName.c_str(),(sampleMapWaitingInput && sampleMapColumn==0 && i>=sampleMapMin && i<=sampleMapMax));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
sampleMapFocused=true;
sampleMapColumn=0;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
ImGui::InhibitInertialScroll();
}
if (sampleMapFocused && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
sampleMapSelEnd=i;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
if (sampleMapSelStart==sampleMapSelEnd) {
sampleMapFocused=true;
sampleMapColumn=0;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
}
if (sampleMapFocused) {
wannaOpenSMPopup=true;
}
}
ImGui::PopFont();
if (ins->type==DIV_INS_NES) {
// pitch
ImGui::TableNextColumn();
ImGui::PushFont(patFont);
ImGui::AlignTextToFramePadding();
ImGui::SetNextItemWidth(ImGui::CalcTextSize("0000").x);
if (sampleMap.dpcmFreq<0) {
2023-10-13 21:16:51 -04:00
sName=fmt::sprintf(" -- ##SD1%d",i);
} else {
2023-10-13 21:16:51 -04:00
sName=fmt::sprintf(" %2d ##SD1%d",sampleMap.dpcmFreq,i);
}
ImGui::Selectable(sName.c_str(),(sampleMapWaitingInput && sampleMapColumn==2 && i>=sampleMapMin && i<=sampleMapMax));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
sampleMapFocused=true;
sampleMapColumn=2;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
ImGui::InhibitInertialScroll();
}
if (sampleMapFocused && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
sampleMapSelEnd=i;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
if (sampleMapSelStart==sampleMapSelEnd) {
sampleMapFocused=true;
sampleMapColumn=2;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
}
if (sampleMapFocused) {
wannaOpenSMPopup=true;
}
}
ImGui::PopFont();
// delta
ImGui::TableNextColumn();
ImGui::PushFont(patFont);
ImGui::AlignTextToFramePadding();
ImGui::SetNextItemWidth(ImGui::CalcTextSize("0000").x);
if (sampleMap.dpcmDelta<0) {
2023-10-13 21:16:51 -04:00
sName=fmt::sprintf(" -- ##SD2%d",i);
} else {
2023-10-13 21:16:51 -04:00
sName=fmt::sprintf(" %2X ##SD2%d",sampleMap.dpcmDelta,i);
}
ImGui::Selectable(sName.c_str(),(sampleMapWaitingInput && sampleMapColumn==3 && i>=sampleMapMin && i<=sampleMapMax));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
sampleMapFocused=true;
sampleMapColumn=3;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
ImGui::InhibitInertialScroll();
}
if (sampleMapFocused && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
sampleMapSelEnd=i;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
if (sampleMapSelStart==sampleMapSelEnd) {
sampleMapFocused=true;
sampleMapColumn=3;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
}
if (sampleMapFocused) {
wannaOpenSMPopup=true;
}
}
ImGui::PopFont();
} else {
ImGui::TableNextColumn();
sName="???";
if ((sampleMap.freq+60)>0 && (sampleMap.freq+60)<180) {
sName=noteNames[sampleMap.freq+60];
}
sName+=fmt::sprintf("##SN%d",i);
ImGui::PushFont(patFont);
ImGui::AlignTextToFramePadding();
ImGui::SetNextItemWidth(ImGui::CalcTextSize("00000").x);
ImGui::Selectable(sName.c_str(),(sampleMapWaitingInput && sampleMapColumn==1 && i>=sampleMapMin && i<=sampleMapMax));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
sampleMapFocused=true;
sampleMapColumn=1;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
ImGui::InhibitInertialScroll();
}
if (sampleMapFocused && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
sampleMapSelEnd=i;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
if (sampleMapSelStart==sampleMapSelEnd) {
sampleMapFocused=true;
sampleMapColumn=1;
sampleMapDigit=0;
sampleMapSelStart=i;
sampleMapSelEnd=i;
sampleMapMin=sampleMapSelStart;
sampleMapMax=sampleMapSelEnd;
if (sampleMapMin>sampleMapMax) {
sampleMapMin^=sampleMapMax;
sampleMapMax^=sampleMapMin;
sampleMapMin^=sampleMapMax;
}
}
if (sampleMapFocused) {
wannaOpenSMPopup=true;
}
}
ImGui::PopFont();
}
ImGui::TableNextColumn();
String prevName="---";
if (sampleMap.map>=0 && sampleMap.map<e->song.sampleLen) {
prevName=e->song.sample[sampleMap.map]->name;
}
ImGui::PushID(i+2);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::BeginCombo("##SMSample",prevName.c_str())) {
if (ImGui::Selectable("---")) {
sampleMap.map=-1;
}
for (int k=0; k<e->song.sampleLen; k++) {
String itemName=fmt::sprintf("%d: %s",k,e->song.sample[k]->name);
if (ImGui::Selectable(itemName.c_str())) {
sampleMap.map=k;
}
}
ImGui::EndCombo();
}
ImGui::PopID();
}
ImGui::PopStyleColor(2);
ImGui::EndTable();
}
} else {
sampleMapFocused=false;
}
ImGui::EndDisabled();
if (wannaOpenSMPopup) {
ImGui::OpenPopup("SampleMapUtils");
}
if (ImGui::BeginPopup("SampleMapUtils",ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings)) {
if (sampleMapSelStart==sampleMapSelEnd && sampleMapSelStart>=0 && sampleMapSelStart<120) {
if (ins->type==DIV_INS_NES) {
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("set entire map to this pitch"))) {
2023-10-13 20:57:36 -04:00
if (sampleMapSelStart>=0 && sampleMapSelStart<120) {
for (int i=0; i<120; i++) {
if (i==sampleMapSelStart) continue;
ins->amiga.noteMap[i].dpcmFreq=ins->amiga.noteMap[sampleMapSelStart].dpcmFreq;
}
}
}
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("set entire map to this delta counter value"))) {
2023-10-13 20:57:36 -04:00
if (sampleMapSelStart>=0 && sampleMapSelStart<120) {
for (int i=0; i<120; i++) {
if (i==sampleMapSelStart) continue;
ins->amiga.noteMap[i].dpcmDelta=ins->amiga.noteMap[sampleMapSelStart].dpcmDelta;
}
}
}
} else {
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("set entire map to this note"))) {
if (sampleMapSelStart>=0 && sampleMapSelStart<120) {
for (int i=0; i<120; i++) {
if (i==sampleMapSelStart) continue;
ins->amiga.noteMap[i].freq=ins->amiga.noteMap[sampleMapSelStart].freq;
}
}
}
}
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("set entire map to this sample"))) {
if (sampleMapSelStart>=0 && sampleMapSelStart<120) {
for (int i=0; i<120; i++) {
if (i==sampleMapSelStart) continue;
ins->amiga.noteMap[i].map=ins->amiga.noteMap[sampleMapSelStart].map;
}
}
}
}
if (ins->type==DIV_INS_NES) {
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("reset pitches"))) {
2023-10-13 20:57:36 -04:00
for (int i=0; i<120; i++) {
ins->amiga.noteMap[i].dpcmFreq=15;
}
}
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("clear delta counter values"))) {
2023-10-13 20:57:36 -04:00
for (int i=0; i<120; i++) {
ins->amiga.noteMap[i].dpcmDelta=-1;
}
}
} else {
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("reset notes"))) {
for (int i=0; i<120; i++) {
ins->amiga.noteMap[i].freq=i;
}
}
}
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("clear map samples"))) {
for (int i=0; i<120; i++) {
ins->amiga.noteMap[i].map=-1;
}
}
ImGui::EndPopup();
}
ImGui::EndTabItem();
} else {
sampleMapFocused=false;
}
}
2024-07-25 20:59:21 -04:00
void FurnaceGUI::insTabFMModernHeader(DivInstrument* ins) {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN));
ImGui::TableNextColumn();
ImGui::TableNextColumn();
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY));
}
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_AR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR));
TOOLTIP_TEXT(FM_NAME(FM_AR));
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_DR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR));
TOOLTIP_TEXT(FM_NAME(FM_DR));
if (settings.susPosition==0) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
TOOLTIP_TEXT(FM_NAME(FM_SL));
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_D2R));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R));
TOOLTIP_TEXT(FM_NAME(FM_D2R));
}
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_RR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR));
TOOLTIP_TEXT(FM_NAME(FM_RR));
if (settings.susPosition==1) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
TOOLTIP_TEXT(FM_NAME(FM_SL));
}
ImGui::TableNextColumn();
if (settings.susPosition==2) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
TOOLTIP_TEXT(FM_NAME(FM_SL));
}
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_TL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL));
TOOLTIP_TEXT(FM_NAME(FM_TL));
if (settings.susPosition==3) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_SL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
TOOLTIP_TEXT(FM_NAME(FM_SL));
}
ImGui::TableNextColumn();
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
CENTER_TEXT(FM_SHORT_NAME(FM_RS));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RS));
TOOLTIP_TEXT(FM_NAME(FM_RS));
} else {
CENTER_TEXT(FM_SHORT_NAME(FM_KSL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_KSL));
TOOLTIP_TEXT(FM_NAME(FM_KSL));
}
if (ins->type==DIV_INS_OPZ) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_EGSHIFT));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_EGSHIFT));
TOOLTIP_TEXT(FM_NAME(FM_EGSHIFT));
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_REV));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_REV));
TOOLTIP_TEXT(FM_NAME(FM_REV));
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL));
}
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_MULT));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_MULT));
TOOLTIP_TEXT(FM_NAME(FM_MULT));
if (ins->type==DIV_INS_OPZ) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_SHORT_NAME(FM_FINE));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_FINE));
TOOLTIP_TEXT(FM_NAME(FM_FINE));
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_CT));
}
ImGui::TableNextColumn();
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
CENTER_TEXT(FM_SHORT_NAME(FM_DT));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT));
TOOLTIP_TEXT(FM_NAME(FM_DT));
ImGui::TableNextColumn();
}
if (ins->type==DIV_INS_ESFM) {
CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DT));
ImGui::TableNextColumn();
}
if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
CENTER_TEXT(FM_SHORT_NAME(FM_DT2));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT2));
TOOLTIP_TEXT(FM_NAME(FM_DT2));
ImGui::TableNextColumn();
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) {
CENTER_TEXT(FM_SHORT_NAME(FM_AM));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM));
TOOLTIP_TEXT(FM_NAME(FM_AM));
} else {
CENTER_TEXT("Other");
ImGui::TextUnformatted("Other");
}
ImGui::TableNextColumn();
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_NAME(FM_WS));
ImGui::TextUnformatted(FM_NAME(FM_WS));
} else if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) {
ImGui::TableNextColumn();
CENTER_TEXT(FM_NAME(FM_SSG));
ImGui::TextUnformatted(FM_NAME(FM_SSG));
}
ImGui::TableNextColumn();
CENTER_TEXT(_("Envelope"));
ImGui::TextUnformatted(_("Envelope"));
}
void FurnaceGUI::insTabFM(DivInstrument* ins) {
int opCount=4;
if (ins->type==DIV_INS_OPLL) opCount=2;
if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2;
bool opsAreMutable=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM);
if (ImGui::BeginTabItem("FM")) {
DivInstrumentFM& fmOrigin=(ins->type==DIV_INS_OPLL && ins->fm.opllPreset>0 && ins->fm.opllPreset<16)?opllPreview:ins->fm;
bool isPresent[4];
int isPresentCount=0;
memset(isPresent,0,4*sizeof(bool));
for (int i=0; i<e->song.systemLen; i++) {
if (e->song.system[i]==DIV_SYSTEM_VRC7) {
isPresent[3]=true;
} else if (e->song.system[i]==DIV_SYSTEM_OPLL || e->song.system[i]==DIV_SYSTEM_OPLL_DRUMS) {
isPresent[(e->song.systemFlags[i].getInt("patchSet",0))&3]=true;
}
}
if (!isPresent[0] && !isPresent[1] && !isPresent[2] && !isPresent[3]) {
isPresent[0]=true;
}
for (int i=0; i<4; i++) {
if (isPresent[i]) isPresentCount++;
}
int presentWhich=0;
for (int i=0; i<4; i++) {
if (isPresent[i]) {
presentWhich=i;
break;
}
}
if (ImGui::BeginTable("fmDetails",3,(ins->type==DIV_INS_ESFM)?ImGuiTableFlags_SizingStretchProp:ImGuiTableFlags_SizingStretchSame)) {
2025-01-28 04:04:01 -05:00
String blockTxt=_("Automatic");
if (ins->fm.block>=1) {
blockTxt=fmt::sprintf("%d",ins->fm.block-1);
}
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.40f:0.0f));
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.25f:0.0f));
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.35f:0.0f));
ImGui::TableNextRow();
switch (ins->type) {
case DIV_INS_FM:
case DIV_INS_OPM:
ImGui::TableNextColumn();
P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable
if (ins->type==DIV_INS_FM) {
P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable
}
ImGui::TableNextColumn();
P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable
P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable
ImGui::TableNextColumn();
if (fmPreviewOn) {
drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
if (!fmPreviewPaused) {
renderFMPreview(ins,1);
WAKE_UP;
}
} else {
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
}
kvsConfig(ins);
break;
case DIV_INS_OPZ:
ImGui::TableNextColumn();
P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable
P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable
P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable
P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable
ImGui::TableNextColumn();
if (fmPreviewOn) {
drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
if (!fmPreviewPaused) {
renderFMPreview(ins,1);
WAKE_UP;
}
} else {
drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
}
kvsConfig(ins);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("Request from TX81Z"))) {
doAction(GUI_ACTION_TX81Z_REQUEST);
}
/*
ImGui::SameLine();
if (ImGui::Button("Send to TX81Z")) {
showError("Coming soon!");
}
*/
break;
case DIV_INS_OPL:
case DIV_INS_OPL_DRUMS: {
bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS);
bool drums=ins->fm.opllPreset==16;
int algMax=fourOp?3:1;
ImGui::TableNextColumn();
ins->fm.alg&=algMax;
P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable
2025-01-28 04:04:01 -05:00
P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable
ImGui::TableNextColumn();
P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable
if (ins->type==DIV_INS_OPL) {
ImGui::BeginDisabled(ins->fm.opllPreset==16);
if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER
ins->fm.ops=fourOp?4:2;
}
ImGui::EndDisabled();
2025-01-28 04:04:01 -05:00
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Drums"),&drums)) { PARAMETER
ins->fm.opllPreset=drums?16:0;
}
}
ImGui::TableNextColumn();
if (fmPreviewOn) {
drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
if (!fmPreviewPaused) {
renderFMPreview(ins,1);
WAKE_UP;
}
} else {
drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
}
kvsConfig(ins);
break;
}
case DIV_INS_OPLL: {
bool dc=fmOrigin.fms;
bool dm=fmOrigin.ams;
bool sus=ins->fm.alg;
ImGui::TableNextColumn();
ImGui::BeginDisabled(ins->fm.opllPreset!=0);
P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable
ImGui::EndDisabled();
2025-01-28 04:04:01 -05:00
P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable
if (ins->fm.opllPreset!=0) {
ins->fm.op[1].tl&=15;
P(CWSliderScalar(_("Volume##TL"),ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER
ins->fm.alg=sus;
}
ImGui::BeginDisabled(ins->fm.opllPreset!=0);
2025-01-28 04:04:01 -05:00
if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER
fmOrigin.fms=dc;
}
ImGui::SameLine();
if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER
fmOrigin.ams=dm;
}
ImGui::EndDisabled();
ImGui::TableNextColumn();
if (fmPreviewOn) {
drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale));
if (!fmPreviewPaused) {
renderFMPreview(ins,1);
WAKE_UP;
}
} else {
drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale));
}
kvsConfig(ins,false);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
2024-05-26 20:31:17 -04:00
if (ImGui::BeginCombo("##LLPreset",_(opllInsNames[presentWhich][ins->fm.opllPreset]))) {
if (isPresentCount>1) {
if (ImGui::BeginTable("LLPresetList",isPresentCount)) {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
for (int i=0; i<4; i++) {
if (!isPresent[i]) continue;
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("%s name"),opllVariants[i]);
}
for (int i=0; i<17; i++) {
ImGui::TableNextRow();
for (int j=0; j<4; j++) {
if (!isPresent[j]) continue;
ImGui::TableNextColumn();
ImGui::PushID(j*17+i);
2024-05-26 20:31:17 -04:00
if (ImGui::Selectable(_(opllInsNames[j][i]))) {
ins->fm.opllPreset=i;
}
ImGui::PopID();
}
}
ImGui::EndTable();
}
} else {
for (int i=0; i<17; i++) {
2024-05-26 20:31:17 -04:00
if (ImGui::Selectable(_(opllInsNames[presentWhich][i]))) {
ins->fm.opllPreset=i;
}
}
}
ImGui::EndCombo();
}
break;
}
case DIV_INS_ESFM: {
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE,_(esfmNoiseModeNames[ins->esfm.noise&3]))); rightClickable
ImGui::TextUnformatted(_(esfmNoiseModeDescriptions[ins->esfm.noise&3]));
ImGui::TableNextColumn();
P(CWSliderScalar(FM_NAME(FM_BLOCK),ImGuiDataType_U8,&ins->fm.block,&_ZERO,&_EIGHT,blockTxt.c_str())); rightClickable
ImGui::TableNextColumn();
if (fmPreviewOn) {
drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
if (!fmPreviewPaused) {
renderFMPreview(ins,1);
WAKE_UP;
}
} else {
drawESFMAlgorithm(ins->esfm, ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale));
}
kvsConfig(ins);
}
default:
break;
}
ImGui::EndTable();
}
if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset==16) {
ImGui::Text(_("this volume slider only works in compatibility (non-drums) system."));
}
if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) {
ins->fm.ops=2;
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Fixed frequency mode"),&ins->fm.fixedDrums));
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("when enabled, drums will be set to the specified frequencies, ignoring the note."));
}
if (ins->fm.fixedDrums) {
int block=0;
int fNum=0;
if (ImGui::BeginTable("fixedDrumSettings",3)) {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Drum"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Block"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("FreqNum"));
2024-05-26 20:31:17 -04:00
DRUM_FREQ(_("Kick"),"##DBlock0","##DFreq0",ins->fm.kickFreq);
DRUM_FREQ(_("Snare/Hi-hat"),"##DBlock1","##DFreq1",ins->fm.snareHatFreq);
DRUM_FREQ(_("Tom/Top"),"##DBlock2","##DFreq2",ins->fm.tomTopFreq);
ImGui::EndTable();
}
}
}
bool willDisplayOps=true;
if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false;
if (!willDisplayOps && ins->type==DIV_INS_OPLL) {
// update OPLL preset preview
if (ins->fm.opllPreset>0 && ins->fm.opllPreset<16) {
const opll_patch_t* patchROM=NULL;
switch (presentWhich) {
case 1:
patchROM=OPLL_GetPatchROM(opll_type_ymf281);
break;
case 2:
patchROM=OPLL_GetPatchROM(opll_type_ym2423);
break;
case 3:
patchROM=OPLL_GetPatchROM(opll_type_ds1001);
break;
default:
patchROM=OPLL_GetPatchROM(opll_type_ym2413);
break;
}
const opll_patch_t* patch=&patchROM[ins->fm.opllPreset-1];
opllPreview.alg=ins->fm.alg;
opllPreview.fb=patch->fb;
2024-09-10 12:10:42 -04:00
opllPreview.fms=patch->dc;
opllPreview.ams=patch->dm;
opllPreview.op[0].tl=patch->tl;
opllPreview.op[1].tl=ins->fm.op[1].tl;
for (int i=0; i<2; i++) {
opllPreview.op[i].am=patch->am[i];
opllPreview.op[i].vib=patch->vib[i];
opllPreview.op[i].ssgEnv=patch->et[i]?8:0;
opllPreview.op[i].ksr=patch->ksr[i];
2024-09-10 12:10:42 -04:00
opllPreview.op[i].ksl=patch->ksl[i];
opllPreview.op[i].mult=patch->multi[i];
opllPreview.op[i].ar=patch->ar[i];
opllPreview.op[i].dr=patch->dr[i];
opllPreview.op[i].sl=patch->sl[i];
opllPreview.op[i].rr=patch->rr[i];
}
}
}
ImGui::BeginDisabled(!willDisplayOps);
2024-07-25 20:59:21 -04:00
if (settings.fmLayout==0 || settings.fmLayout==7) {
int numCols=15;
if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13;
if (ins->type==DIV_INS_OPLL) numCols=12;
if (ins->type==DIV_INS_OPZ) numCols=19;
if (ins->type==DIV_INS_ESFM) numCols=19;
if (ImGui::BeginTable("FMOperators",numCols,ImGuiTableFlags_SizingStretchProp|ImGuiTableFlags_BordersH|ImGuiTableFlags_BordersOuterV)) {
// configure columns
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); // op name
if (ins->type==DIV_INS_ESFM) {
ImGui::TableSetupColumn("c0e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl
ImGui::TableSetupColumn("c0e1",ImGuiTableColumnFlags_WidthFixed); // -separator-
ImGui::TableSetupColumn("c0e2",ImGuiTableColumnFlags_WidthStretch,0.05f); // delay
}
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.05f); // ar
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.05f); // dr
2025-03-14 14:55:43 -04:00
if (settings.susPosition==0) {
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch,0.05f); // d2r
}
ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthStretch,0.05f); // rr
2025-03-14 14:55:43 -04:00
if (settings.susPosition==1) {
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl
}
ImGui::TableSetupColumn("c6",ImGuiTableColumnFlags_WidthFixed); // -separator-
2025-03-14 14:55:43 -04:00
if (settings.susPosition==2) {
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl
}
ImGui::TableSetupColumn("c7",ImGuiTableColumnFlags_WidthStretch,0.05f); // tl
2025-03-14 14:55:43 -04:00
if (settings.susPosition==3) {
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl
}
ImGui::TableSetupColumn("c8",ImGuiTableColumnFlags_WidthStretch,0.05f); // rs/ksl
if (ins->type==DIV_INS_OPZ) {
ImGui::TableSetupColumn("c8z0",ImGuiTableColumnFlags_WidthStretch,0.05f); // egs
ImGui::TableSetupColumn("c8z1",ImGuiTableColumnFlags_WidthStretch,0.05f); // rev
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableSetupColumn("c8e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl
}
ImGui::TableSetupColumn("c9",ImGuiTableColumnFlags_WidthStretch,0.05f); // mult
if (ins->type==DIV_INS_OPZ) {
ImGui::TableSetupColumn("c9z",ImGuiTableColumnFlags_WidthStretch,0.05f); // fine
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableSetupColumn("c9e",ImGuiTableColumnFlags_WidthStretch,0.05f); // ct
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) {
ImGui::TableSetupColumn("c10",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt
}
if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::TableSetupColumn("c11",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt2
}
ImGui::TableSetupColumn("c15",ImGuiTableColumnFlags_WidthFixed); // am
ImGui::TableSetupColumn("c12",ImGuiTableColumnFlags_WidthFixed); // -separator-
if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) {
ImGui::TableSetupColumn("c13",ImGuiTableColumnFlags_WidthStretch,0.2f); // ssg/waveform
}
ImGui::TableSetupColumn("c14",ImGuiTableColumnFlags_WidthStretch,0.3f); // env
2024-07-25 20:59:21 -04:00
float sliderHeight=((ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()*(settings.fmLayout==7?4.0f:1.0f))/opCount)-ImGui::GetStyle().ItemSpacing.y;
// header
2024-07-25 20:59:21 -04:00
if (settings.fmLayout==0) {
insTabFMModernHeader(ins);
}
2024-07-25 20:59:21 -04:00
// main view
for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i];
DivInstrumentESFM::Operator& opE=ins->esfm.op[i];
2024-07-25 20:59:21 -04:00
// modern with more labels
if (settings.fmLayout==7) {
insTabFMModernHeader(ins);
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
// push colors
if (settings.separateFMColors) {
bool mod=true;
if (ins->type==DIV_INS_OPL_DRUMS) {
mod=false;
} else if (ins->type==DIV_INS_ESFM) {
// this is the same as the KVS heuristic in platform/esfm.h
if (opE.outLvl==7) {
mod=false;
} else if (opE.outLvl>0) {
if (i==3) {
mod=false;
} else {
DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1];
if (opENext.modIn==0) {
mod=false;
} else if ((opE.outLvl-opENext.modIn)>=2) {
mod=false;
}
}
}
} else if (opCount==4) {
if (ins->type==DIV_INS_OPL) {
if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false;
} else {
if (opIsOutput[fmOrigin.alg&7][i]) mod=false;
}
} else {
if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false;
}
if (mod) {
pushAccentColors(
uiColors[GUI_COLOR_FM_PRIMARY_MOD],
uiColors[GUI_COLOR_FM_SECONDARY_MOD],
uiColors[GUI_COLOR_FM_BORDER_MOD],
uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD]
);
} else {
pushAccentColors(
uiColors[GUI_COLOR_FM_PRIMARY_CAR],
uiColors[GUI_COLOR_FM_SECONDARY_CAR],
uiColors[GUI_COLOR_FM_BORDER_CAR],
uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR]
);
}
}
if (i==0) {
float sliderMinHeightOPL=ImGui::GetFrameHeight()*4.0+ImGui::GetStyle().ItemSpacing.y*3.0;
float sliderMinHeightESFM=ImGui::GetFrameHeight()*5.0+ImGui::GetStyle().ItemSpacing.y*4.0;
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL) && sliderHeight<sliderMinHeightOPL) {
sliderHeight=sliderMinHeightOPL;
}
if (ins->type==DIV_INS_ESFM && sliderHeight<sliderMinHeightESFM) {
sliderHeight=sliderMinHeightESFM;
}
}
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
String opNameLabel;
if (ins->type==DIV_INS_OPL_DRUMS) {
opNameLabel=fmt::sprintf("%s",oplDrumNames[i]);
} else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) {
if (i==1) {
2024-05-26 20:31:17 -04:00
opNameLabel=_("Kick");
} else {
2024-05-26 20:31:17 -04:00
opNameLabel=_("Env");
}
} else {
opNameLabel=fmt::sprintf("OP%d",i+1);
}
if (opsAreMutable) {
pushToggleColors(op.enable);
if (ImGui::Button(opNameLabel.c_str())) {
op.enable=!op.enable;
PARAMETER;
}
popToggleColors();
} else {
ImGui::TextUnformatted(opNameLabel.c_str());
}
// drag point
OP_DRAG_POINT;
2022-02-17 13:08:17 -05:00
int maxTl=127;
if (ins->type==DIV_INS_OPLL) {
if (i==1) {
maxTl=15;
} else {
maxTl=63;
}
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
maxTl=63;
}
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15;
bool ssgOn=op.ssgEnv&8;
bool ksrOn=op.ksr;
bool vibOn=op.vib;
bool susOn=op.sus;
bool fixedOn=opE.fixed;
unsigned char ssgEnv=op.ssgEnv&7;
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##MODIN",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
ImGui::TableNextColumn();
opE.delay&=7;
CENTER_VSLIDER;
P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable
}
ImGui::TableNextColumn();
op.ar&=maxArDr;
CENTER_VSLIDER;
P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable
ImGui::TableNextColumn();
op.dr&=maxArDr;
CENTER_VSLIDER;
P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable
if (settings.susPosition==0) {
ImGui::TableNextColumn();
op.sl&=15;
CENTER_VSLIDER;
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::TableNextColumn();
op.d2r&=31;
CENTER_VSLIDER;
P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable
}
ImGui::TableNextColumn();
op.rr&=15;
CENTER_VSLIDER;
P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable
2024-07-25 21:03:10 -04:00
if (settings.susPosition==1) {
ImGui::TableNextColumn();
op.sl&=15;
CENTER_VSLIDER;
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
}
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
2024-07-25 21:03:10 -04:00
if (settings.susPosition==2) {
ImGui::TableNextColumn();
op.sl&=15;
CENTER_VSLIDER;
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
}
ImGui::TableNextColumn();
op.tl&=maxTl;
CENTER_VSLIDER;
P(CWVSliderScalar("##TL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable
2024-07-25 21:03:10 -04:00
if (settings.susPosition==3) {
ImGui::TableNextColumn();
op.sl&=15;
CENTER_VSLIDER;
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
}
ImGui::TableNextColumn();
CENTER_VSLIDER;
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
P(CWVSliderScalar("##RS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable
} else {
int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3];
if (CWVSliderInt("##KSL",ImVec2(20.0f*dpiScale,sliderHeight),&ksl,0,3)) {
op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]);
PARAMETER;
} rightClickable
}
if (ins->type==DIV_INS_OPZ) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##EGS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##REV",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##OUTLVL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable
}
ImGui::TableNextColumn();
2024-11-11 03:57:23 -05:00
pushWarningColor(ins->type==DIV_INS_OPL_DRUMS && i==0);
CENTER_VSLIDER;
P(CWVSliderScalar("##MULT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable
2024-11-11 03:57:23 -05:00
if (ins->type==DIV_INS_OPL_DRUMS && i==0) {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s",_("Snare's multiplier is determined by HiHat's."));
}
}
popWarningColor();
if (ins->type==DIV_INS_OPZ) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
2024-08-25 06:33:01 -04:00
bool egtOn=op.egt;
2024-09-22 04:58:17 -04:00
if (!egtOn) {
2024-08-25 06:33:01 -04:00
P(CWVSliderScalar("##FINE",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable
}
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##CT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7];
ImGui::TableNextColumn();
CENTER_VSLIDER;
if (CWVSliderInt("##DT",ImVec2(20.0f*dpiScale,sliderHeight),&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4)) { PARAMETER
if (detune<-3) detune=-3;
if (detune>7) detune=7;
op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3];
} rightClickable
if (ins->type!=DIV_INS_FM) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##DT2",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable
}
ImGui::TableNextColumn();
bool amOn=op.am;
if (ins->type==DIV_INS_OPZ) {
bool egtOn=op.egt;
bool susOn=op.sus;
if (egtOn) {
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*4.0-ImGui::GetStyle().ItemSpacing.y*3.5));
} else {
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*2.0-ImGui::GetStyle().ItemSpacing.y*1.0));
}
if (ImGui::Checkbox("AM",&amOn)) { PARAMETER
op.am=amOn;
}
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Fixed"),&egtOn)) { PARAMETER
op.egt=egtOn;
}
if (egtOn) {
pushWarningColor(susOn && e->song.linearPitch!=2);
if (ImGui::Checkbox(_("Pitch control"),&susOn)) { PARAMETER
op.sus=susOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->temp.vZoom[DIV_MACRO_OP_SSG+(i<<5)]=-1;
ins->temp.vZoom[DIV_MACRO_OP_SUS+(i<<5)]=-1;
}
popWarningColor();
2024-09-22 04:58:17 -04:00
if (ImGui::IsItemHovered()) {
if (susOn && e->song.linearPitch!=2) {
ImGui::SetTooltip(_("only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full."));
} else {
ImGui::SetTooltip(_("use op's arpeggio and pitch macros control instead of block/f-num macros"));
}
}
}
if (egtOn && !susOn) {
int block=op.dt;
int freqNum=(op.mult<<4)|(op.dvb&15);
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Block"),&block,1,1)) {
if (block<0) block=0;
if (block>7) block=7;
op.dt=block;
}
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("FreqNum"),&freqNum,1,16)) {
if (freqNum<0) freqNum=0;
if (freqNum>255) freqNum=255;
op.mult=freqNum>>4;
op.dvb=freqNum&15;
}
}
} else {
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()));
if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER
op.am=amOn;
}
}
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ && ins->type!=DIV_INS_OPM) {
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
ImGui::TableNextColumn();
ImGui::BeginDisabled(!ssgOn);
drawSSGEnv(op.ssgEnv&7,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing()));
ImGui::EndDisabled();
if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
2024-05-26 20:31:17 -04:00
if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,_(ssgEnvTypes[ssgEnv]))) { PARAMETER
op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7);
}
}
} else if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
CENTER_VSLIDER;
P(CWVSliderScalar("##DT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable
ImGui::TableNextColumn();
bool amOn=op.am;
bool leftOn=opE.left;
bool rightOn=opE.right;
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*5.0-ImGui::GetStyle().ItemSpacing.y*4.0));
ImVec2 curPosBeforeDummy = ImGui::GetCursorPos();
ImGui::Dummy(ImVec2(ImGui::GetFrameHeightWithSpacing()*2.0f+ImGui::CalcTextSize(FM_SHORT_NAME(FM_DAM)).x*2.0f,1.0f));
ImGui::SetCursorPos(curPosBeforeDummy);
if (ImGui::BeginTable("panCheckboxes",(fixedOn)?3:2,ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,1.0);
if (fixedOn) {
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,1.2);
}
float yCoordBeforeTablePadding=ImGui::GetCursorPosY();
2023-10-22 10:46:34 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yCoordBeforeTablePadding);
if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER
opE.left=leftOn;
}
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yCoordBeforeTablePadding);
if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER
opE.right=rightOn;
}
if (fixedOn) {
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yCoordBeforeTablePadding);
if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
}
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER
op.ksr=ksrOn;
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER
op.sus=susOn;
}
if (fixedOn) {
bool damOn=op.dam;
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER
op.dam=damOn;
}
}
ImGui::EndTable();
}
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-0.5*ImGui::GetStyle().ItemSpacing.y);
if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER
opE.fixed=fixedOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->temp.vZoom[DIV_MACRO_OP_SSG+(i<<5)]=-1;
ins->temp.vZoom[DIV_MACRO_OP_DT+(i<<5)]=-1;
}
if (ins->type==DIV_INS_ESFM) {
if (fixedOn) {
int block=(opE.ct>>2)&7;
int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt);
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Block"),&block,1,1)) {
if (block<0) block=0;
if (block>7) block=7;
opE.ct=(opE.ct&(~(7<<2)))|(block<<2);
}
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("FreqNum"),&freqNum,1,16)) {
if (freqNum<0) freqNum=0;
if (freqNum>1023) freqNum=1023;
opE.dt=freqNum&0xff;
opE.ct=(opE.ct&(~3))|(freqNum>>8);
2023-10-22 10:46:34 -04:00
}
} else {
if (ImGui::BeginTable("amVibCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0);
float yCoordBeforeTablePadding=ImGui::GetCursorPosY();
ImGui::TableNextRow();
2023-10-22 10:46:34 -04:00
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yCoordBeforeTablePadding);
if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
2023-10-22 10:46:34 -04:00
}
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yCoordBeforeTablePadding);
if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
2023-10-22 10:46:34 -04:00
}
bool damOn=op.dam;
bool dvbOn=op.dvb;
ImGui::TableNextRow();
2023-10-22 10:46:34 -04:00
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER
op.dam=damOn;
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER
op.dvb=dvbOn;
}
ImGui::EndTable();
}
}
2022-02-17 13:08:17 -05:00
}
} else if (ins->type!=DIV_INS_OPM) {
ImGui::TableNextColumn();
bool amOn=op.am;
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*4.0-ImGui::GetStyle().ItemSpacing.y*3.0));
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
}
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
}
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
op.ksr=ksrOn;
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER
op.sus=susOn;
}
} else if (ins->type==DIV_INS_OPLL) {
if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
}
}
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) {
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
ImGui::TableNextColumn();
2022-11-15 17:51:43 -05:00
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_ESFM && fixedOn)?3.0f:1.0f)));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
2024-09-09 07:26:59 -04:00
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
}
if (ins->type==DIV_INS_ESFM && fixedOn) {
if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
}
bool dvbOn=op.dvb;
if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER
op.dvb=dvbOn;
2022-11-15 17:51:43 -05:00
}
}
} else if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPM) {
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale));
}
ImGui::TableNextColumn();
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type);
2022-11-15 17:51:43 -05:00
if (settings.separateFMColors) {
popAccentColors();
}
ImGui::PopID();
}
2022-11-15 17:51:43 -05:00
ImGui::EndTable();
}
} else if (settings.fmLayout>=4 && settings.fmLayout<=6) { // alternate
int columns=2;
switch (settings.fmLayout) {
case 4: // 2x2
columns=2;
break;
case 5: // 1x4
columns=1;
break;
case 6: // 4x1
columns=opCount;
break;
}
char tempID[1024];
ImVec2 oldPadding=ImGui::GetStyle().CellPadding;
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale));
if (ImGui::BeginTable("AltFMOperators",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) {
for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i];
DivInstrumentESFM::Operator& opE=ins->esfm.op[i];
if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
// push colors
if (settings.separateFMColors) {
bool mod=true;
if (ins->type==DIV_INS_OPL_DRUMS) {
mod=false;
} else if (ins->type==DIV_INS_ESFM) {
// this is the same as the KVS heuristic in platform/esfm.h
if (opE.outLvl==7) mod=false;
else if (opE.outLvl>0) {
if (i==3) mod=false;
else {
DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1];
if (opENext.modIn==0) mod=false;
else if ((opE.outLvl-opENext.modIn)>=2) mod=false;
2022-11-15 17:51:43 -05:00
}
}
} else if (opCount==4) {
if (ins->type==DIV_INS_OPL) {
if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false;
} else {
if (opIsOutput[fmOrigin.alg&7][i]) mod=false;
}
} else {
if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false;
}
if (mod) {
pushAccentColors(
uiColors[GUI_COLOR_FM_PRIMARY_MOD],
uiColors[GUI_COLOR_FM_SECONDARY_MOD],
uiColors[GUI_COLOR_FM_BORDER_MOD],
uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD]
);
} else {
pushAccentColors(
uiColors[GUI_COLOR_FM_PRIMARY_CAR],
uiColors[GUI_COLOR_FM_SECONDARY_CAR],
uiColors[GUI_COLOR_FM_BORDER_CAR],
uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR]
);
}
}
2022-11-15 17:51:43 -05:00
ImGui::Dummy(ImVec2(dpiScale,dpiScale));
if (ins->type==DIV_INS_OPL_DRUMS) {
snprintf(tempID,1024,"%s",oplDrumNames[i]);
} else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) {
if (i==1) {
2024-05-26 20:31:17 -04:00
snprintf(tempID,1024,_("Envelope 2 (kick only)"));
} else {
2024-05-26 20:31:17 -04:00
snprintf(tempID,1024,_("Envelope"));
}
} else {
2024-05-26 20:31:17 -04:00
snprintf(tempID,1024,_("Operator %d"),i+1);
}
float nextCursorPosX=ImGui::GetCursorPosX()+0.5*(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(tempID).x-(opsAreMutable?(ImGui::GetStyle().FramePadding.x*2.0f):0.0f));
OP_DRAG_POINT;
ImGui::SameLine();
ImGui::SetCursorPosX(nextCursorPosX);
if (opsAreMutable) {
pushToggleColors(op.enable);
if (ImGui::Button(tempID)) {
op.enable=!op.enable;
PARAMETER;
}
popToggleColors();
} else {
ImGui::TextUnformatted(tempID);
}
2022-11-15 17:51:43 -05:00
float sliderHeight=200.0f*dpiScale;
float waveWidth=140.0*dpiScale*((ins->type==DIV_INS_ESFM)?0.85f:1.0f);
float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL || ins->type==DIV_INS_ESFM)?5.0f:4.5f);
int maxTl=127;
if (ins->type==DIV_INS_OPLL) {
if (i==1) {
maxTl=15;
} else {
maxTl=63;
}
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
maxTl=63;
}
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15;
bool ssgOn=op.ssgEnv&8;
bool ksrOn=op.ksr;
bool vibOn=op.vib;
bool egtOn=op.egt;
bool susOn=op.sus; // yawn
unsigned char ssgEnv=op.ssgEnv&7;
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,oldPadding);
if (ImGui::BeginTable("opParams",4,ImGuiTableFlags_BordersInnerV)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,waveWidth);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableNextRow();
ImGui::TableNextColumn();
float textY=ImGui::GetCursorPosY();
if (ins->type==DIV_INS_ESFM) {
CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_DELAY));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY));
} else {
CENTER_TEXT_20(FM_SHORT_NAME(FM_AR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR));
TOOLTIP_TEXT(FM_NAME(FM_AR));
}
ImGui::TableNextColumn();
if (ins->type==DIV_INS_FM) {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("SSG-EG"));
} else if (ins->type!=DIV_INS_OPM) {
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Waveform"));
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Envelope"));
ImGui::TableNextColumn();
2022-11-15 17:51:43 -05:00
// A/D/S/R
ImGui::TableNextColumn();
if (ins->type==DIV_INS_ESFM) {
opE.delay&=7;
P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable
ImGui::SameLine();
}
2022-11-15 17:51:43 -05:00
op.ar&=maxArDr;
float textX_AR=ImGui::GetCursorPosX();
P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable
ImGui::SameLine();
op.dr&=maxArDr;
float textX_DR=ImGui::GetCursorPosX();
P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable
2022-11-15 17:51:43 -05:00
float textX_SL=0.0f;
if (settings.susPosition==0) {
ImGui::SameLine();
op.sl&=15;
textX_SL=ImGui::GetCursorPosX();
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
}
2022-03-26 18:30:26 -04:00
float textX_D2R=0.0f;
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::SameLine();
op.d2r&=31;
textX_D2R=ImGui::GetCursorPosX();
P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable
}
2022-02-23 11:51:02 -05:00
ImGui::SameLine();
op.rr&=15;
float textX_RR=ImGui::GetCursorPosX();
P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable
2022-11-15 17:51:43 -05:00
2024-07-25 20:36:40 -04:00
if (settings.susPosition>0) {
ImGui::SameLine();
op.sl&=15;
textX_SL=ImGui::GetCursorPosX();
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
}
2022-11-15 17:51:43 -05:00
ImVec2 prevCurPos=ImGui::GetCursorPos();
2022-11-15 17:51:43 -05:00
// labels
if (ins->type==DIV_INS_ESFM) {
ImGui::SetCursorPos(ImVec2(textX_AR,textY));
CENTER_TEXT_20(FM_SHORT_NAME(FM_AR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR));
TOOLTIP_TEXT(FM_NAME(FM_AR));
}
2022-11-15 17:51:43 -05:00
ImGui::SetCursorPos(ImVec2(textX_DR,textY));
CENTER_TEXT_20(FM_SHORT_NAME(FM_DR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR));
TOOLTIP_TEXT(FM_NAME(FM_DR));
ImGui::SetCursorPos(ImVec2(textX_SL,textY));
CENTER_TEXT_20(FM_SHORT_NAME(FM_SL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
TOOLTIP_TEXT(FM_NAME(FM_SL));
ImGui::SetCursorPos(ImVec2(textX_RR,textY));
CENTER_TEXT_20(FM_SHORT_NAME(FM_RR));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR));
TOOLTIP_TEXT(FM_NAME(FM_RR));
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::SetCursorPos(ImVec2(textX_D2R,textY));
CENTER_TEXT_20(FM_SHORT_NAME(FM_D2R));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R));
TOOLTIP_TEXT(FM_NAME(FM_D2R));
}
2022-11-15 17:51:43 -05:00
ImGui::SetCursorPos(prevCurPos);
ImGui::TableNextColumn();
switch (ins->type) {
case DIV_INS_FM: {
// SSG
ImGui::BeginDisabled(!ssgOn);
drawSSGEnv(op.ssgEnv&7,ImVec2(waveWidth,waveHeight));
ImGui::EndDisabled();
if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
}
2022-11-15 17:51:43 -05:00
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
2024-05-26 20:31:17 -04:00
if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,_(ssgEnvTypes[ssgEnv]))) { PARAMETER
op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7);
}
// params
ImGui::Separator();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7];
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT));
if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER
if (detune<-3) detune=-3;
if (detune>7) detune=7;
op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3];
} rightClickable
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS));
P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable
break;
}
case DIV_INS_OPM: {
// params
ImGui::Separator();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7];
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT));
if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER
if (detune<-3) detune=-3;
if (detune>7) detune=7;
op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3];
} rightClickable
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2));
P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS));
P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable
break;
}
case DIV_INS_OPLL:
// waveform
drawWaveform(i==0?(fmOrigin.ams&1):(fmOrigin.fms&1),ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
2022-11-15 17:51:43 -05:00
// params
ImGui::Separator();
if (ImGui::BeginTable("FMParamsInner",2)) {
ImGui::TableNextRow();
2022-02-23 11:51:02 -05:00
ImGui::TableNextColumn();
bool amOn=op.am;
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
op.ksr=ksrOn;
}
2022-11-15 17:51:43 -05:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
}
2022-02-23 11:51:02 -05:00
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
}
ImGui::EndTable();
}
2022-11-15 17:51:43 -05:00
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL));
P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable
2022-11-15 17:51:43 -05:00
break;
case DIV_INS_OPL:
case DIV_INS_OPL_DRUMS: {
// waveform
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
2024-09-09 07:26:59 -04:00
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
}
2022-11-15 17:51:43 -05:00
// params
ImGui::Separator();
if (ImGui::BeginTable("FMParamsInner",2)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
bool amOn=op.am;
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
op.ksr=ksrOn;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER
op.sus=susOn;
}
ImGui::EndTable();
}
2022-11-15 17:51:43 -05:00
2024-11-11 03:57:23 -05:00
pushWarningColor(ins->type==DIV_INS_OPL_DRUMS && i==0);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
2024-11-11 03:57:23 -05:00
if (ins->type==DIV_INS_OPL_DRUMS && i==0) {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s",_("Snare's multiplier is determined by HiHat's."));
}
}
popWarningColor();
2022-11-15 17:51:43 -05:00
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL));
int ksl=kslMap[op.ksl&3];
if (CWSliderInt("##KSL",&ksl,0,3,tempID)) {
op.ksl=kslMap[ksl&3];
PARAMETER;
} rightClickable
break;
}
case DIV_INS_OPZ: {
// waveform
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
2024-09-09 07:26:59 -04:00
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
}
// params
ImGui::Separator();
if (egtOn) {
2024-09-22 04:58:17 -04:00
if (!op.sus) {
int block=op.dt;
int freqNum=(op.mult<<4)|(op.dvb&15);
ImGui::Text(_("Block"));
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImVec2 cursorAlign=ImGui::GetCursorPos();
if (ImGui::InputInt("##Block",&block,1,1)) {
if (block<0) block=0;
if (block>7) block=7;
op.dt=block;
}
ImGui::Text(_("Freq"));
ImGui::SameLine();
ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY()));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) {
if (freqNum<0) freqNum=0;
if (freqNum>255) freqNum=255;
op.mult=freqNum>>4;
op.dvb=freqNum&15;
}
2022-11-15 17:51:43 -05:00
}
} else {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7];
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT));
if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER
if (detune<-3) detune=-3;
if (detune>7) detune=7;
op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3];
} rightClickable
2022-11-15 17:51:43 -05:00
}
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2));
P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable
if (ImGui::IsItemHovered()) {
2024-08-25 11:19:39 -04:00
ImGui::SetTooltip(_("Only on YM2151 and YM2414 (OPM and OPZ)"));
}
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS));
P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable
break;
2022-11-15 17:51:43 -05:00
}
case DIV_INS_ESFM:
// waveform
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
// params
ImGui::Separator();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
if (opE.fixed) {
int block=(opE.ct>>2)&7;
int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt);
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Blk"));
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Block"));
}
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
//ImVec2 cursorAlign=ImGui::GetCursorPos();
if (ImGui::InputInt("##Block",&block,1,1)) {
if (block<0) block=0;
if (block>7) block=7;
opE.ct=(opE.ct&(~(7<<2)))|(block<<2);
2022-11-15 17:51:43 -05:00
}
2024-05-26 20:31:17 -04:00
ImGui::Text(_("F"));
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Frequency (F-Num)"));
2022-11-15 17:51:43 -05:00
}
ImGui::SameLine();
//ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY()));
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) {
if (freqNum<0) freqNum=0;
if (freqNum>1023) freqNum=1023;
opE.dt=freqNum&0xff;
opE.ct=(opE.ct&(~3))|(freqNum>>8);
2022-11-15 17:51:43 -05:00
}
} else {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT));
P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR,tempID)); rightClickable
2022-11-15 17:51:43 -05:00
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT));
P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN,tempID)); rightClickable
}
2022-11-15 17:51:43 -05:00
if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f);
float yPosOutsideTablePadding=ImGui::GetCursorPosY();
bool leftOn=opE.left;
bool rightOn=opE.right;
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yPosOutsideTablePadding);
if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER
opE.left=leftOn;
2022-11-15 17:51:43 -05:00
}
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yPosOutsideTablePadding);
if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER
opE.right=rightOn;
2022-11-15 17:51:43 -05:00
}
ImGui::EndTable();
}
break;
default:
break;
}
ImGui::TableNextColumn();
float envHeight=sliderHeight;//-ImGui::GetStyle().ItemSpacing.y*2.0f;
if (ins->type==DIV_INS_OPZ) {
envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f;
}
if (ins->type==DIV_INS_ESFM) {
envHeight-=ImGui::GetFrameHeightWithSpacing()*3.0f;
}
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type);
2022-11-15 17:51:43 -05:00
if (ins->type==DIV_INS_OPZ) {
ImGui::Separator();
if (ImGui::BeginTable("FMParamsInnerOPZ",2)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (!egtOn) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_FINE));
P(CWSliderScalar("##FINE",ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN,tempID)); rightClickable
2024-09-22 04:58:17 -04:00
} else {
2024-08-25 06:33:01 -04:00
bool susOn=op.sus;
pushWarningColor(susOn && e->song.linearPitch!=2);
if (ImGui::Checkbox(_("Pitch control"),&susOn)) { PARAMETER
2024-08-25 06:33:01 -04:00
op.sus=susOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->temp.vZoom[DIV_MACRO_OP_SSG+(i<<5)]=-1;
ins->temp.vZoom[DIV_MACRO_OP_SUS+(i<<5)]=-1;
2024-08-25 06:33:01 -04:00
}
popWarningColor();
2024-09-22 04:58:17 -04:00
if (ImGui::IsItemHovered()) {
if (susOn && e->song.linearPitch!=2) {
ImGui::SetTooltip(_("only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full."));
} else {
ImGui::SetTooltip(_("use op's arpeggio and pitch macros control instead of block/f-num macros"));
}
2024-08-25 06:33:01 -04:00
}
}
2023-10-14 13:00:31 -04:00
ImGui::TableNextColumn();
bool amOn=op.am;
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Fixed"),&egtOn)) { PARAMETER
op.egt=egtOn;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_EGSHIFT));
P(CWSliderScalar("##EGShift",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_REV));
P(CWSliderScalar("##REV",ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN,tempID)); rightClickable
2022-02-23 11:51:02 -05:00
ImGui::TableNextColumn();
2023-10-14 13:00:31 -04:00
ImGui::EndTable();
}
}
2023-10-14 13:00:31 -04:00
if (ins->type==DIV_INS_ESFM) {
ImGui::Separator();
if (ImGui::BeginTable("FMParamsInnerESFM",2)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.64f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.36f);
ImGui::TableNextRow();
ImGui::TableNextColumn();
2022-03-08 13:12:20 -05:00
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL));
int ksl=kslMap[op.ksl&3];
if (CWSliderInt("##KSL",&ksl,0,3,tempID)) {
op.ksl=kslMap[ksl&3];
PARAMETER;
} rightClickable
2022-06-13 04:54:42 -04:00
bool amOn=op.am;
bool fixedOn=opE.fixed;
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER
op.ksr=ksrOn;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginTable("vibAmCheckboxes",2)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f);
2023-10-14 13:00:31 -04:00
float yPosOutsideTablePadding=ImGui::GetCursorPosY();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yPosOutsideTablePadding);
if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
2022-11-15 17:51:43 -05:00
}
ImGui::TableNextColumn();
ImGui::SetCursorPosY(yPosOutsideTablePadding);
if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
2022-06-13 04:54:42 -04:00
}
2022-11-15 17:51:43 -05:00
bool damOn=op.dam;
bool dvbOn=op.dvb;
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER
op.dvb=dvbOn;
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER
op.dam=damOn;
}
ImGui::EndTable();
}
ImGui::TableNextColumn();
if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER
op.sus=susOn;
}
if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER
opE.fixed=fixedOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->temp.vZoom[DIV_MACRO_OP_SSG+(i<<5)]=-1;
ins->temp.vZoom[DIV_MACRO_OP_DT+(i<<5)]=-1;
}
2022-11-15 17:51:43 -05:00
ImGui::EndTable();
}
}
ImGui::TableNextColumn();
op.tl&=maxTl;
float tlSliderWidth=(ins->type==DIV_INS_ESFM)?20.0f*dpiScale:ImGui::GetFrameHeight();
float tlSliderHeight=sliderHeight-((ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM)?(ImGui::GetFrameHeightWithSpacing()+ImGui::CalcTextSize(FM_SHORT_NAME(FM_AM)).y+ImGui::GetStyle().ItemSpacing.y):0.0f);
float textX_tl=ImGui::GetCursorPosX();
P(CWVSliderScalar("##TL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) {
CENTER_TEXT(FM_SHORT_NAME(FM_AM));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM));
TOOLTIP_TEXT(FM_NAME(FM_AM));
bool amOn=op.am;
if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER
op.am=amOn;
2022-11-15 17:51:43 -05:00
}
}
if (ins->type==DIV_INS_ESFM) {
ImGui::SameLine();
float textX_outLvl=ImGui::GetCursorPosX();
P(CWVSliderScalar("##OUTLVL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable
2022-11-15 17:51:43 -05:00
ImGui::SameLine();
float textX_modIn=ImGui::GetCursorPosX();
P(CWVSliderScalar("##MODIN",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable
prevCurPos=ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(textX_tl,textY));
CENTER_TEXT_20(FM_SHORT_NAME(FM_TL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL));
TOOLTIP_TEXT(FM_NAME(FM_TL));
ImGui::SetCursorPos(ImVec2(textX_outLvl,textY));
CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_OUTLVL));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL));
ImGui::SetCursorPos(ImVec2(textX_modIn,textY));
CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_MODIN));
ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN));
TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN));
ImGui::SetCursorPos(prevCurPos);
} else {
prevCurPos=ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(textX_tl,textY));
CENTER_TEXT(FM_SHORT_NAME(FM_TL));
ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL));
TOOLTIP_TEXT(FM_NAME(FM_TL));
2022-11-15 17:51:43 -05:00
ImGui::SetCursorPos(prevCurPos);
}
2022-11-15 17:51:43 -05:00
ImGui::EndTable();
}
ImGui::PopStyleVar();
if (settings.separateFMColors) {
popAccentColors();
}
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::PopStyleVar();
} else { // classic
int columns=2;
switch (settings.fmLayout) {
case 1: // 2x2
columns=2;
break;
case 2: // 1x4
columns=1;
break;
case 3: // 4x1
columns=opCount;
break;
}
if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) {
for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i];
DivInstrumentESFM::Operator& opE=ins->esfm.op[i];
if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Separator();
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
// push colors
if (settings.separateFMColors) {
bool mod=true;
if (ins->type==DIV_INS_OPL_DRUMS) {
mod=false;
} else if (ins->type==DIV_INS_ESFM) {
// this is the same as the KVS heuristic in platform/esfm.h
if (opE.outLvl==7) {
mod=false;
} else if (opE.outLvl>0) {
if (i==3) {
mod=false;
} else {
DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1];
if (opENext.modIn==0) {
mod=false;
} else if ((opE.outLvl-opENext.modIn)>=2) {
mod=false;
2022-11-15 17:51:43 -05:00
}
}
}
} else if (opCount==4) {
if (ins->type==DIV_INS_OPL) {
if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false;
} else {
if (opIsOutput[fmOrigin.alg&7][i]) mod=false;
}
} else {
if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false;
}
if (mod) {
pushAccentColors(
uiColors[GUI_COLOR_FM_PRIMARY_MOD],
uiColors[GUI_COLOR_FM_SECONDARY_MOD],
uiColors[GUI_COLOR_FM_BORDER_MOD],
uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD]
);
} else {
pushAccentColors(
uiColors[GUI_COLOR_FM_PRIMARY_CAR],
uiColors[GUI_COLOR_FM_SECONDARY_CAR],
uiColors[GUI_COLOR_FM_BORDER_CAR],
uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR]
);
}
}
2022-09-22 00:25:57 -04:00
ImGui::Dummy(ImVec2(dpiScale,dpiScale));
String opNameLabel;
OP_DRAG_POINT;
ImGui::SameLine();
if (ins->type==DIV_INS_OPL_DRUMS) {
opNameLabel=fmt::sprintf("%s",oplDrumNames[i]);
} else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) {
if (i==1) {
2024-05-26 20:31:17 -04:00
opNameLabel=_("Envelope 2 (kick only)");
} else {
2024-05-26 20:31:17 -04:00
opNameLabel=_("Envelope");
}
} else {
opNameLabel=fmt::sprintf("OP%d",i+1);
}
if (opsAreMutable) {
pushToggleColors(op.enable);
if (ImGui::Button(opNameLabel.c_str())) {
op.enable=!op.enable;
PARAMETER;
}
popToggleColors();
} else {
ImGui::TextUnformatted(opNameLabel.c_str());
}
ImGui::SameLine();
2022-09-22 00:25:57 -04:00
bool amOn=op.am;
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
op.am=amOn;
}
int maxTl=127;
if (ins->type==DIV_INS_OPLL) {
if (i==1) {
maxTl=15;
} else {
maxTl=63;
}
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
maxTl=63;
}
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15;
bool ssgOn=op.ssgEnv&8;
bool ksrOn=op.ksr;
bool vibOn=op.vib;
bool susOn=op.sus; // don't you make fun of this one
unsigned char ssgEnv=op.ssgEnv&7;
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ && ins->type!=DIV_INS_OPM && ins->type!=DIV_INS_ESFM) {
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox((ins->type==DIV_INS_OPLL)?FM_NAME(FM_EGS):_("SSG On"),&ssgOn)) { PARAMETER
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
}
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
ImGui::SameLine();
if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER
op.sus=susOn;
}
}
if (ins->type==DIV_INS_OPZ) {
ImGui::SameLine();
bool fixedOn=op.egt;
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Fixed"),&fixedOn)) { PARAMETER
op.egt=fixedOn;
}
2024-08-25 06:33:01 -04:00
bool susOn=op.sus;
2024-09-22 04:58:17 -04:00
if (fixedOn) {
2024-08-25 06:33:01 -04:00
ImGui::SameLine();
pushWarningColor(susOn && e->song.linearPitch!=2);
if (ImGui::Checkbox(_("Pitch control"),&susOn)) { PARAMETER
2024-08-25 06:33:01 -04:00
op.sus=susOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->temp.vZoom[DIV_MACRO_OP_SSG+(i<<5)]=-1;
ins->temp.vZoom[DIV_MACRO_OP_SUS+(i<<5)]=-1;
2024-08-25 06:33:01 -04:00
}
popWarningColor();
2024-09-22 04:58:17 -04:00
if (ImGui::IsItemHovered()) {
if (susOn && e->song.linearPitch!=2) {
ImGui::SetTooltip(_("only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full."));
} else {
ImGui::SetTooltip(_("use op's arpeggio and pitch macros control instead of block/f-num macros"));
}
2024-08-25 06:33:01 -04:00
}
}
}
//52.0 controls vert scaling; default 96
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type);
//P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable
if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0); \
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
opE.delay&=7;
P(CWSliderScalar("##DELAY",ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",ESFM_NAME(ESFM_DELAY));
}
2022-11-15 17:51:43 -05:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
op.ar&=maxArDr;
P(CWSliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_AR));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
op.dr&=maxArDr;
P(CWSliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_DR));
if (settings.susPosition==0) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_SL));
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##D2R",ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_D2R));
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##RR",ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_RR));
2024-07-25 20:36:40 -04:00
if (settings.susPosition>0) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_SL));
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
op.tl&=maxTl;
P(CWSliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_TL));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Separator();
ImGui::TableNextColumn();
ImGui::Separator();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_RS));
} else {
int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3];
if (CWSliderInt("##KSL",&ksl,0,3)) {
op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]);
PARAMETER;
} rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_KSL));
}
if (ins->type==DIV_INS_OPZ) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar(FM_NAME(FM_EGSHIFT),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_EGSHIFT));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar(FM_NAME(FM_REV),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_REV));
}
if (ins->type==DIV_INS_OPZ) {
if (op.egt) {
bool susOn=op.sus;
2024-09-22 04:58:17 -04:00
if (!susOn) {
int block=op.dt;
int freqNum=(op.mult<<4)|(op.dvb&15);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt(FM_NAME(FM_MULT),&block,0,7)) { PARAMETER
if (block<0) block=0;
if (block>7) block=7;
op.dt=block;
} rightClickable
ImGui::TableNextColumn();
ImGui::Text("Block");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt(FM_NAME(FM_FINE),&freqNum,0,255)) { PARAMETER
if (freqNum<0) freqNum=0;
if (freqNum>255) freqNum=255;
op.mult=freqNum>>4;
op.dvb=freqNum&15;
} rightClickable
ImGui::TableNextColumn();
ImGui::Text(_("FreqNum"));
}
} else {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_MULT));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar(FM_NAME(FM_FINE),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_FINE));
}
} else {
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-11-11 03:57:23 -05:00
pushWarningColor(ins->type==DIV_INS_OPL_DRUMS && i==0);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable
2024-11-11 03:57:23 -05:00
if (ins->type==DIV_INS_OPL_DRUMS && i==0) {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s",_("Snare's multiplier is determined by HiHat's."));
}
}
popWarningColor();
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_MULT));
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
if (!(ins->type==DIV_INS_OPZ && op.egt)) {
int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4)) { PARAMETER
if (detune<-3) detune=-3;
if (detune>7) detune=7;
op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3];
} rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_DT));
}
if (ins->type!=DIV_INS_FM) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_DT2));
}
2022-11-15 17:51:43 -05:00
if (ins->type==DIV_INS_FM) { // OPN only
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
2024-05-26 20:31:17 -04:00
if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,_(ssgEnvTypes[ssgEnv]))) { PARAMETER
op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7);
} rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_SSG));
}
}
if (ins->type==DIV_INS_ESFM) {
bool fixedOn=opE.fixed;
if (fixedOn) {
int block=(opE.ct>>2)&7;
int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##Block",&block,1,1)) {
if (block<0) block=0;
if (block>7) block=7;
opE.ct=(opE.ct&(~(7<<2)))|(block<<2);
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Block"));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) {
if (freqNum<0) freqNum=0;
if (freqNum>1023) freqNum=1023;
opE.dt=freqNum&0xff;
opE.ct=(opE.ct&(~3))|(freqNum>>8);
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("FreqNum"));
} else {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",ESFM_NAME(ESFM_CT));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",ESFM_NAME(ESFM_DT));
}
}
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
2024-09-09 07:26:59 -04:00
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
}
ImGui::TableNextColumn();
ImGui::Text("%s",FM_NAME(FM_WS));
}
if (ins->type==DIV_INS_ESFM) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Separator();
ImGui::TableNextColumn();
ImGui::Separator();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##OUTLVL",ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",ESFM_NAME(ESFM_OUTLVL));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##MODIN",ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
ImGui::Text("%s",ESFM_NAME(ESFM_MODIN));
}
ImGui::EndTable();
}
if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
op.vib=vibOn;
}
ImGui::SameLine();
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
op.ksr=ksrOn;
}
}
if (ins->type==DIV_INS_ESFM) {
bool dvbOn=op.dvb;
bool damOn=op.dam;
bool leftOn=opE.left;
bool rightOn=opE.right;
bool fixedOn=opE.fixed;
if (ImGui::Checkbox(FM_NAME(FM_DVB),&dvbOn)) { PARAMETER
op.dvb=dvbOn;
}
ImGui::SameLine();
if (ImGui::Checkbox(FM_NAME(FM_DAM),&damOn)) { PARAMETER
op.dam=damOn;
}
if (ImGui::Checkbox(ESFM_NAME(ESFM_LEFT),&leftOn)) { PARAMETER
opE.left=leftOn;
}
ImGui::SameLine();
if (ImGui::Checkbox(ESFM_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER
opE.right=rightOn;
}
ImGui::SameLine();
if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER
opE.fixed=fixedOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->temp.vZoom[DIV_MACRO_OP_SSG+(i<<5)]=-1;
ins->temp.vZoom[DIV_MACRO_OP_DT+(i<<5)]=-1;
}
}
if (settings.separateFMColors) {
popAccentColors();
}
ImGui::PopID();
}
ImGui::EndTable();
}
}
ImGui::EndDisabled();
ImGui::EndTabItem();
}
}
void FurnaceGUI::drawInsSID3(DivInstrument* ins) {
char buffer[100];
char buffer2[100];
if (ImGui::BeginTabItem("SID3")) {
if (ImGui::BeginTable("sid3Waves",2,0)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0f);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Waveform"));
ImGui::SameLine();
pushToggleColors(ins->sid3.triOn);
if (ImGui::Button(_("tri"))) { PARAMETER
ins->sid3.triOn=!ins->sid3.triOn;
}
popToggleColors();
ImGui::SameLine();
pushToggleColors(ins->sid3.sawOn);
if (ImGui::Button(_("saw"))) { PARAMETER
ins->sid3.sawOn=!ins->sid3.sawOn;
}
popToggleColors();
ImGui::SameLine();
pushToggleColors(ins->sid3.pulseOn);
if (ImGui::Button(_("pulse"))) { PARAMETER
ins->sid3.pulseOn=!ins->sid3.pulseOn;
}
popToggleColors();
ImGui::SameLine();
pushToggleColors(ins->sid3.noiseOn);
if (ImGui::Button(_("noise"))) { PARAMETER
ins->sid3.noiseOn=!ins->sid3.noiseOn;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Like in SID2,specific noise LFSR feedback bits config can produce tonal waves.\n"
2024-08-17 06:49:56 -04:00
"Refer to the manual for LFSR bits macro configurations for which frequency calculation is altered\n"
"in a way that makes tonal noise stay in tune."));
}
popToggleColors();
ImGui::SameLine();
P(ImGui::Checkbox(_("1-bit noise"),&ins->sid3.oneBitNoise));
ImGui::SameLine();
pushToggleColors(ins->sid3.specialWaveOn);
if (ImGui::Button(_("special"))) { PARAMETER
ins->sid3.specialWaveOn=!ins->sid3.specialWaveOn;
}
popToggleColors();
P(CWSliderScalar(_("Special wave"),ImGuiDataType_U8,&ins->sid3.special_wave,&_ZERO,&_SID3_SPECIAL_WAVES,_(sid3SpecialWaveforms[ins->sid3.special_wave%SID3_NUM_SPECIAL_WAVES]))); rightClickable
if (ImGui::Checkbox(_("Wavetable channel"),&ins->sid3.doWavetable)) {
PARAMETER;
ins->temp.vZoom[DIV_MACRO_WAVE]=-1;
for (int i=0; i<256; i++) {
ins->std.waveMacro.val[i]=0;
}
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Forces waveform macro to control wavetable index."));
}
bool invLeft=ins->sid3.phaseInv&SID3_INV_SIGNAL_LEFT;
if (ImGui::Checkbox(_("Inv. left"),&invLeft)) { PARAMETER
ins->sid3.phaseInv^=SID3_INV_SIGNAL_LEFT;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Invert left channel signal"));
}
ImGui::SameLine();
bool invRight=ins->sid3.phaseInv&SID3_INV_SIGNAL_RIGHT;
if (ImGui::Checkbox(_("Inv. right"),&invRight)) { PARAMETER
ins->sid3.phaseInv^=SID3_INV_SIGNAL_RIGHT;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Invert right channel signal"));
}
ImGui::TableNextColumn();
2024-08-10 08:32:05 -04:00
CENTER_TEXT(_("Special wave preview"));
ImGui::TextUnformatted(_("Special wave preview"));
drawWaveformSID3(ins->sid3.special_wave,ImVec2(120.0f*dpiScale,70.0f*dpiScale));
ImGui::EndTable();
}
ImVec2 sliderSize=ImVec2(30.0f*dpiScale,256.0*dpiScale);
if (ImGui::BeginTable("SID3EnvParams",6,ImGuiTableFlags_NoHostExtendX)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
CENTER_TEXT(_("A"));
ImGui::TextUnformatted(_("A"));
ImGui::TableNextColumn();
CENTER_TEXT(_("D"));
ImGui::TextUnformatted(_("D"));
ImGui::TableNextColumn();
CENTER_TEXT(_("S"));
ImGui::TextUnformatted(_("S"));
ImGui::TableNextColumn();
CENTER_TEXT(_("SR"));
ImGui::TextUnformatted(_("SR"));
ImGui::TableNextColumn();
CENTER_TEXT(_("R"));
ImGui::TextUnformatted(_("R"));
ImGui::TableNextColumn();
CENTER_TEXT(_("Envelope"));
ImGui::TextUnformatted(_("Envelope"));
ImGui::TableNextRow();
ImGui::TableNextColumn();
P(CWVSliderScalar("##Attack",sliderSize,ImGuiDataType_U8,&ins->sid3.a,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay",sliderSize,ImGuiDataType_U8,&ins->sid3.d,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Sustain",sliderSize,ImGuiDataType_U8,&ins->sid3.s,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##SustainRate",sliderSize,ImGuiDataType_U8,&ins->sid3.sr,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Release",sliderSize,ImGuiDataType_U8,&ins->sid3.r,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::TableNextColumn();
// the (ins->sid3.r==15?(ins->sid3.r-1):ins->sid3.r) is used so release part never becomes horizontal (which isn't the case with SID3 envelope)
drawSID3Env(0,(ins->sid3.a==0?(255):(256-ins->sid3.a)),(ins->sid3.d==0?(255):(256-ins->sid3.d)),ins->sid3.sr,255-(ins->sid3.r==255?(ins->sid3.r-1):ins->sid3.r),255-ins->sid3.s,0,0,0,255,256,255,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type);
ImGui::EndTable();
}
if (!ins->sid3.doWavetable) {
strncpy(buffer,macroSID3WaveMixMode(0,(float)ins->sid3.mixMode,NULL).c_str(),40);
P(CWSliderScalar(_("Wave Mix Mode"),ImGuiDataType_U8,&ins->sid3.mixMode,&_ZERO,&_FOUR,buffer));
P(CWSliderScalar(_("Duty"),ImGuiDataType_U16,&ins->sid3.duty,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable
P(CWSliderScalar(_("Feedback"),ImGuiDataType_U8,&ins->sid3.feedback,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE));
bool resetDuty=ins->sid3.resetDuty;
if (ImGui::Checkbox(_("Reset duty on new note"),&resetDuty)) { PARAMETER
ins->sid3.resetDuty=resetDuty;
}
if (ImGui::Checkbox(_("Absolute Duty Macro"),&ins->sid3.dutyIsAbs)) {
ins->temp.vZoom[DIV_MACRO_DUTY]=-1;
PARAMETER;
}
}
bool ringMod=ins->sid3.ringMod;
if (ImGui::Checkbox(_("Ring Modulation"),&ringMod)) { PARAMETER
ins->sid3.ringMod=ringMod;
}
2024-08-04 04:32:28 -04:00
ImGui::SameLine();
strncpy(buffer,macroSID3SourceChan(0,(float)ins->sid3.ring_mod_source,NULL).c_str(),40);
2024-08-04 04:32:28 -04:00
P(CWSliderScalar(_("Source channel##rmsrc"),ImGuiDataType_U8,&ins->sid3.ring_mod_source,&_ZERO,&_SID3_NUM_CHANNELS,buffer));
bool oscSync=ins->sid3.oscSync;
if (ImGui::Checkbox(_("Oscillator Sync"),&oscSync)) { PARAMETER
ins->sid3.oscSync=oscSync;
}
2024-08-04 04:32:28 -04:00
ImGui::SameLine();
strncpy(buffer,macroSID3SourceChan(0,(float)ins->sid3.sync_source,NULL).c_str(),40);
P(CWSliderScalar(_("Source channel##hssrc"),ImGuiDataType_U8,&ins->sid3.sync_source,&_ZERO,&_SID3_NUM_CHANNELS_MINUS_ONE,buffer));
bool phaseMod=ins->sid3.phase_mod;
if (ImGui::Checkbox(_("Phase modulation"),&phaseMod)) { PARAMETER
ins->sid3.phase_mod=phaseMod;
}
2024-08-04 04:32:28 -04:00
ImGui::SameLine();
strncpy(buffer,macroSID3SourceChan(0,(float)ins->sid3.phase_mod_source,NULL).c_str(),40);
P(CWSliderScalar(_("Source channel##pmsrc"),ImGuiDataType_U8,&ins->sid3.phase_mod_source,&_ZERO,&_SID3_NUM_CHANNELS_MINUS_ONE,buffer));
ImGui::Separator();
if (!ins->sid3.doWavetable) {
bool sepNoisePitch=ins->sid3.separateNoisePitch;
if (ImGui::Checkbox(_("Separate noise pitch"),&sepNoisePitch)) { PARAMETER
ins->sid3.separateNoisePitch=sepNoisePitch;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Make noise pitch independent from other waves' pitch.\nNoise pitch will be controllable via macros."));
}
}
2024-08-04 04:32:28 -04:00
for (int i=0; i<SID3_NUM_FILTERS; i++) {
DivInstrumentSID3::Filter* filt=&ins->sid3.filt[i];
if (filt->enabled) {
ImGui::Separator();
}
bool enable=filt->enabled;
snprintf(buffer,100,_("Enable filter %d"),i+1);
if (ImGui::Checkbox(buffer,&enable)) { PARAMETER
filt->enabled=enable;
}
if (filt->enabled) {
bool init=filt->init;
snprintf(buffer,100,_("Initialize filter %d"),i+1);
if (ImGui::Checkbox(buffer,&init)) { PARAMETER
filt->init=init;
}
ImGui::SameLine();
snprintf(buffer,100,_("Connect to channel input##contoinput%d"),i+1);
bool toInput=filt->mode&SID3_FILTER_CHANNEL_INPUT;
if (ImGui::Checkbox(buffer,&toInput)) { PARAMETER
filt->mode^=SID3_FILTER_CHANNEL_INPUT;
}
snprintf(buffer,100,_("Cutoff##fcut%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U16,&filt->cutoff,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable
snprintf(buffer,100,_("Resonance##fres%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->resonance,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
snprintf(buffer,100,_("Output volume##foutvol%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->output_volume,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
snprintf(buffer,100,_("Distortion level##fdist%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->distortion_level,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
ImGui::AlignTextToFramePadding();
ImGui::Text(_("Filter Mode"));
ImGui::SameLine();
bool lp=filt->mode&SID3_FILTER_LP;
pushToggleColors(lp);
snprintf(buffer,100,_("low##flow%d"),i+1);
if (ImGui::Button(buffer)) { PARAMETER
filt->mode^=SID3_FILTER_LP;
}
popToggleColors();
ImGui::SameLine();
bool bp=filt->mode&SID3_FILTER_BP;
pushToggleColors(bp);
snprintf(buffer,100,_("band##fband%d"),i+1);
if (ImGui::Button(buffer)) { PARAMETER
filt->mode^=SID3_FILTER_BP;
}
popToggleColors();
ImGui::SameLine();
bool hp=filt->mode&SID3_FILTER_HP;
pushToggleColors(hp);
snprintf(buffer,100,_("high##fhigh%d"),i+1);
if (ImGui::Button(buffer)) { PARAMETER
filt->mode^=SID3_FILTER_HP;
}
popToggleColors();
ImGui::SameLine();
snprintf(buffer,100,_("Connect to channel output##contooutput%d"),i+1);
bool toOutput=filt->mode&SID3_FILTER_OUTPUT;
if (ImGui::Checkbox(buffer,&toOutput)) { PARAMETER
filt->mode^=SID3_FILTER_OUTPUT;
}
snprintf(buffer,100,_("Absolute cutoff macro##abscutoff%d"),i+1);
bool absCutoff=filt->absoluteCutoff;
if (ImGui::Checkbox(buffer,&absCutoff)) { PARAMETER
filt->absoluteCutoff=!filt->absoluteCutoff;
ins->temp.vZoom[DIV_MACRO_OP_D2R+(i<<5)]=-1;
}
snprintf(buffer,100,_("Change cutoff with pitch##bindcutoff%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindCutoffToNote));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter cutoff will change with frequency/pitch.\nSee settings below."));
}
if (filt->bindCutoffToNote) {
snprintf(buffer,100,_("Decrease cutoff when pitch increases##decreasecutoff%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindCutoffToNoteDir));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("If this is enabled,filter cutoff will decrease if you increase the pitch.\n"
"If this is disabled,filter cutoff will increase if you increase the pitch."));
}
snprintf(buffer2,100,_("%s"),noteNameNormal(filt->bindCutoffToNoteCenter%12,(short)(filt->bindCutoffToNoteCenter / 12)-5));
snprintf(buffer,100,_("Cutoff change center note##bindcutcenternote%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindCutoffToNoteCenter,&_ZERO,&_ONE_HUNDRED_SEVENTY_NINE,buffer2)); rightClickable
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("The center note for cutoff changes. At this note no cutoff change happens.\nAs pitch goes lower or higher,cutoff changes apply."));
}
snprintf(buffer,100,_("Cutoff change strength##bindcutstrength%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindCutoffToNoteStrength,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("How much cutoff changes for given pitch change."));
}
snprintf(buffer,100,_("Scale cutoff only once on new note##bindcutnn%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindCutoffOnNote));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter cutoff will be changed only once on new note.\nIf this option is disabled,cutoff scaling will be applied\nevery time a pitch change happens."));
}
}
snprintf(buffer,100,_("Change resonance with pitch##bindres%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindResonanceToNote));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter resonance will change with frequency/pitch.\nSee settings below."));
}
if (filt->bindResonanceToNote) {
snprintf(buffer,100,_("Decrease resonance when pitch increases##decreaseres%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindResonanceToNoteDir));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("If this is enabled,filter resonance will decrease if you increase the pitch.\n"
"If this is disabled,filter resonance will increase if you increase the pitch."));
}
snprintf(buffer2,100,_("%s"),noteNameNormal(filt->bindResonanceToNoteCenter%12,(short)(filt->bindResonanceToNoteCenter / 12)-5));
snprintf(buffer,100,_("Resonance change center note##bindrescenternote%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindResonanceToNoteCenter,&_ZERO,&_ONE_HUNDRED_SEVENTY_NINE,buffer2)); rightClickable
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("The center note for resonance changes. At this note no resonance change happens.\nAs pitch goes lower or higher,resonance changes apply."));
}
snprintf(buffer,100,_("Resonance change strength##bindresstrength%d"),i+1);
P(CWSliderScalar(buffer,ImGuiDataType_U8,&filt->bindResonanceToNoteStrength,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("How much resonance changes for given pitch change."));
}
snprintf(buffer,100,_("Scale resonance only once on new note##bindresnn%d"),i+1);
P(ImGui::Checkbox(buffer,&filt->bindResonanceOnNote));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Filter resonance will be changed only once on new note.\nIf this option is disabled,resonance scaling will be applied\nevery time a pitch change happens."));
}
}
}
}
ImGui::Separator();
if (ImGui::BeginTable("SID3filtmatrix",1)) {
if (waveGenVisible) ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,250.0f*dpiScale);
ImGui::TableNextRow();
ImGui::TableNextColumn();
CENTER_TEXT(_("Filters connection matrix"));
ImGui::Text(_("Filters connection matrix"));
if (ImGui::BeginTable("SID3checkboxesmatrix",3+SID3_NUM_FILTERS)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text(">>");
ImGui::TableNextColumn();
ImGui::Text(_("In"));
for (int i=0; i<SID3_NUM_FILTERS; i++) {
ImGui::TableNextColumn();
ImGui::Text("%d",i+1);
}
ImGui::TableNextColumn();
ImGui::Text(_("Out"));
ImGui::TableNextRow();
for (int i=0; i<SID3_NUM_FILTERS; i++) {
DivInstrumentSID3::Filter* filt=&ins->sid3.filt[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%d",i+1);
ImGui::TableNextColumn();
snprintf(buffer,40,"##filtmatrixin%d",i+1);
bool toInput=filt->mode&SID3_FILTER_CHANNEL_INPUT;
if (ImGui::Checkbox(buffer,&toInput)) { PARAMETER
filt->mode^=SID3_FILTER_CHANNEL_INPUT;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Feed signal from channel to filter %d input"),i+1);
}
for (int j=0; j<SID3_NUM_FILTERS; j++) {
ImGui::TableNextColumn();
snprintf(buffer,40,"##filtmatrix%d%d",i+1,j+1);
bool enable=filt->filter_matrix&(1<<j);
if (ImGui::Checkbox(buffer,&enable)) { PARAMETER
filt->filter_matrix^=(1<<j);
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Feed signal from filter %d output to filter %d input"),j+1,i+1);
}
}
ImGui::TableNextColumn();
snprintf(buffer,40,"##filtmatrixout%d",i+1);
bool toOutput=filt->mode&SID3_FILTER_OUTPUT;
if (ImGui::Checkbox(buffer,&toOutput)) { PARAMETER
filt->mode^=SID3_FILTER_OUTPUT;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Feed signal from filter %d output to channel output"),i+1);
}
}
ImGui::EndTable();
}
ImGui::EndTable();
}
ImGui::EndTabItem();
}
if (!ins->amiga.useSample) {
insTabWavetable(ins);
}
insTabSample(ins);
std::vector<FurnaceGUIMacroDesc> macroList;
for (int i=0; i<SID3_NUM_FILTERS; i++) {
snprintf(buffer,40,_("Filter %d macros"),i+1);
if (ImGui::BeginTabItem(buffer)) {
macroList.push_back(FurnaceGUIMacroDesc(_("Cutoff"),&ins->std.opMacros[i].d2rMacro,ins->sid3.filt[i].absoluteCutoff?0:-65535,65535,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Resonance"),&ins->std.opMacros[i].damMacro,0,255,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Toggle"),&ins->std.opMacros[i].drMacro,0,1,32,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Mode"),&ins->std.opMacros[i].ksrMacro,0,3,48,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true,filtModeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Distortion Level"),&ins->std.opMacros[i].dt2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Output Volume"),&ins->std.opMacros[i].dtMacro,0,255,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Channel Input Connection"),&ins->std.opMacros[i].dvbMacro,0,1,32,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Channel Output Connection"),&ins->std.opMacros[i].egtMacro,0,1,32,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Connection Matrix Row"),&ins->std.opMacros[i].kslMacro,0,SID3_NUM_FILTERS,16*SID3_NUM_FILTERS,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true,sid3FilterMatrixBits));
2025-03-10 13:46:46 -04:00
drawMacros(macroList,macroEditStateOP[i],ins);
ImGui::EndTabItem();
}
}
}
void FurnaceGUI::drawInsEdit() {
if (nextWindow==GUI_WINDOW_INS_EDIT) {
insEditOpen=true;
ImGui::SetNextWindowFocus();
nextWindow=GUI_WINDOW_NOTHING;
}
if (!insEditOpen) return;
if (mobileUI) {
patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*canvasH)):ImVec2((0.16*canvasH)+0.5*canvasW*mobileMenuPos,0.0f));
patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)-(pianoOpen?(0.4*canvasW):0.0f)):ImVec2(canvasW-(0.16*canvasH),canvasH-(pianoOpen?(0.3*canvasH):0.0f)));
ImGui::SetNextWindowPos(patWindowPos);
ImGui::SetNextWindowSize(patWindowSize);
} else {
ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
}
2024-05-27 18:53:46 -04:00
if (ImGui::Begin("Instrument Editor",&insEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking),_("Instrument Editor"))) {
DivInstrument* ins=NULL;
if (curIns==-2) {
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)*0.5f);
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("waiting..."));
ImGui::Text(_("waiting..."));
} else if (curIns<0 || curIns>=(int)e->song.ins.size()) {
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()*(e->song.ins.empty()?2.0f:3.0f)+ImGui::GetStyle().ItemSpacing.y)*0.5f);
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("no instrument selected"));
ImGui::Text(_("no instrument selected"));
if (ImGui::BeginTable("noAssetCenter",3)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.5f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.5f);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableNextColumn();
if (e->song.ins.size()>0) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
2024-05-26 20:31:17 -04:00
if (ImGui::BeginCombo("##InsSelect",_("select one..."))) {
String name;
for (size_t i=0; i<e->song.ins.size(); i++) {
name=fmt::sprintf("%.2X: %s##_INSS%d",i,e->song.ins[i]->name,i);
if (ImGui::Selectable(name.c_str(),curIns==(int)i)) {
curIns=i;
wavePreviewInit=true;
updateFMPreview=true;
ins = e->song.ins[curIns];
}
}
ImGui::EndCombo();
}
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::TextUnformatted(_("or"));
ImGui::SameLine();
}
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("Open"))) {
doAction(GUI_ACTION_INS_LIST_OPEN);
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
ImGui::TextUnformatted(_("or"));
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("Create New"))) {
doAction(GUI_ACTION_INS_LIST_ADD);
}
ImGui::TableNextColumn();
ImGui::EndTable();
}
} else {
ins=e->song.ins[curIns];
if (updateFMPreview) {
renderFMPreview(ins);
updateFMPreview=false;
}
if (settings.insEditColorize) {
if (ins->type>=DIV_INS_MAX) {
pushAccentColors(uiColors[GUI_COLOR_INSTR_UNKNOWN],uiColors[GUI_COLOR_INSTR_UNKNOWN],uiColors[GUI_COLOR_INSTR_UNKNOWN],ImVec4(0.0f,0.0f,0.0f,0.0f));
} else {
pushAccentColors(uiColors[GUI_COLOR_INSTR_STD+ins->type],uiColors[GUI_COLOR_INSTR_STD+ins->type],uiColors[GUI_COLOR_INSTR_STD+ins->type],ImVec4(0.0f,0.0f,0.0f,0.0f));
}
}
if (ImGui::BeginTable("InsProp",3)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
String insIndex=fmt::sprintf("%.2X",curIns);
ImGui::SetNextItemWidth(72.0f*dpiScale);
if (ImGui::BeginCombo("##InsSelect",insIndex.c_str())) {
String name;
for (size_t i=0; i<e->song.ins.size(); i++) {
name=fmt::sprintf("%.2X: %s##_INSS%d",i,e->song.ins[i]->name,i);
if (ImGui::Selectable(name.c_str(),curIns==(int)i)) {
curIns=i;
ins=e->song.ins[curIns];
wavePreviewInit=true;
updateFMPreview=true;
}
}
ImGui::EndCombo();
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Name"));
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::PushID(2+curIns);
if (ImGui::InputText("##Name",&ins->name)) {
MARK_MODIFIED;
}
ImGui::PopID();
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Button(ICON_FA_FOLDER_OPEN "##IELoad")) {
doAction(GUI_ACTION_INS_LIST_OPEN_REPLACE);
}
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Open"));
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_FLOPPY_O "##IESave")) {
doAction(GUI_ACTION_INS_LIST_SAVE);
}
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Save"));
}
if (ImGui::BeginPopupContextItem("InsSaveFormats",ImGuiMouseButton_Right)) {
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("save as .dmp..."))) {
doAction(GUI_ACTION_INS_LIST_SAVE_DMP);
}
ImGui::EndPopup();
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Type"));
ImGui::TableNextColumn();
int insType=ins->type;
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
bool warnType=true;
for (DivInstrumentType i: e->getPossibleInsTypes()) {
if (i==insType) {
warnType=false;
}
}
pushWarningColor(warnType,warnType && failedNoteOn);
2024-05-26 20:31:17 -04:00
if (ImGui::BeginCombo("##Type",(insType>=DIV_INS_MAX)?_("Unknown"):_(insTypes[insType][0]))) {
std::vector<DivInstrumentType> insTypeList;
if (settings.displayAllInsTypes) {
for (int i=0; insTypes[i][0]; i++) {
insTypeList.push_back((DivInstrumentType)i);
}
} else {
insTypeList=e->getPossibleInsTypes();
}
for (DivInstrumentType i: insTypeList) {
if (ImGui::Selectable(insTypes[i][0],insType==i)) {
ins->type=i;
// reset macro zoom
memset(ins->temp.vZoom,-1,sizeof(ins->temp.vZoom));
2022-02-17 13:08:17 -05:00
}
}
ImGui::EndCombo();
} else if (warnType) {
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("none of the currently present chips are able to play this instrument type!"));
}
}
popWarningColor();
ImGui::EndTable();
}
if (ImGui::BeginTabBar("insEditTab")) {
std::vector<FurnaceGUIMacroDesc> macroList;
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) {
char label[32];
int opCount=4;
if (ins->type==DIV_INS_OPLL) opCount=2;
if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2;
insTabFM(ins);
2023-10-17 18:24:57 -04:00
if (ins->type!=DIV_INS_ESFM) {
2024-05-26 20:31:17 -04:00
if (ImGui::BeginTabItem(_("FM Macros"))) {
2023-10-17 18:24:57 -04:00
if (ins->type==DIV_INS_OPLL) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DC),&ins->std.fmsMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DM),&ins->std.amsMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
} else {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_ALG),&ins->std.algMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS) {
if (ins->type==DIV_INS_OPZ) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER]));
2025-03-23 05:22:43 -04:00
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS2),&ins->std.ex9Macro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS2),&ins->std.ex10Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER]));
2023-10-17 18:24:57 -04:00
} else {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER]));
}
2022-04-10 01:01:55 -04:00
}
}
2023-10-17 18:24:57 -04:00
if (ins->type==DIV_INS_FM) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Speed"),&ins->std.ex3Macro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER]));
2023-10-17 18:24:57 -04:00
}
if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("AM Depth"),&ins->std.ex1Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("PM Depth"),&ins->std.ex2Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Speed"),&ins->std.ex3Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Shape"),&ins->std.waveMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves));
2023-10-17 18:24:57 -04:00
}
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("OpMask"),&ins->std.ex4Macro,0,4,128,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,fmOperatorBits));
2023-10-17 18:24:57 -04:00
} else if (ins->type==DIV_INS_OPZ) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("AM Depth 2"),&ins->std.ex5Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("PM Depth 2"),&ins->std.ex6Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("LFO2 Speed"),&ins->std.ex7Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("LFO2 Shape"),&ins->std.ex8Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves));
2023-10-17 18:24:57 -04:00
}
2025-03-10 13:46:46 -04:00
drawMacros(macroList,macroEditStateFM,ins);
2023-10-17 18:24:57 -04:00
ImGui::EndTabItem();
2022-02-28 18:16:05 -05:00
}
2022-02-17 13:08:17 -05:00
}
for (int i=0; i<opCount; i++) {
if (ins->type==DIV_INS_OPL_DRUMS) {
if (i>0) break;
2024-05-26 20:31:17 -04:00
snprintf(label,31,_("Operator Macros"));
} else {
2024-05-26 20:31:17 -04:00
snprintf(label,31,_("OP%d Macros"),i+1);
}
2022-02-17 13:08:17 -05:00
if (ImGui::BeginTabItem(label)) {
ImGui::PushID(i);
int ordi=(opCount==4 && ins->type!=DIV_INS_ESFM)?orderedOps[i]:i;
int maxTl=127;
if (ins->type==DIV_INS_OPLL) {
if (i==1) {
maxTl=15;
} else {
maxTl=63;
}
}
2023-10-17 18:24:57 -04:00
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
maxTl=63;
}
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15;
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSL),&ins->std.opMacros[ordi].kslMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_WS),&ins->std.opMacros[ordi].wsMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER]));
2022-09-25 05:32:34 -04:00
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.opMacros[ordi].susMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
} else if (ins->type==DIV_INS_OPLL) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSL),&ins->std.opMacros[ordi].kslMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
2022-09-25 05:32:34 -04:00
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_EGS),&ins->std.opMacros[ordi].egtMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
2023-10-17 18:24:57 -04:00
} else if (ins->type==DIV_INS_ESFM) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_VOLUME]));
2024-08-25 06:33:01 -04:00
if (ins->esfm.op[ordi].fixed) {
macroList.push_back(FurnaceGUIMacroDesc(_("Block"),&ins->std.opMacros[ordi].ssgMacro,0,7,64,uiColors[GUI_COLOR_MACRO_PITCH],true));
macroList.push_back(FurnaceGUIMacroDesc(_("FreqNum"),&ins->std.opMacros[ordi].dtMacro,0,1023,160,uiColors[GUI_COLOR_MACRO_PITCH]));
} else {
macroList.push_back(FurnaceGUIMacroDesc(_("Op. Arpeggio"),&ins->std.opMacros[ordi].ssgMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.opMacros[ordi].ssgMacro.val,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Op. Pitch"),&ins->std.opMacros[ordi].dtMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode,NULL,false,NULL,false,NULL,false,true));
}
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_DELAY),&ins->std.opMacros[ordi].dt2Macro,0,7,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
2023-10-17 18:24:57 -04:00
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSL),&ins->std.opMacros[ordi].kslMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_WS),&ins->std.opMacros[ordi].wsMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_OUTLVL),&ins->std.opMacros[ordi].egtMacro,0,7,64,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_MODIN),&ins->std.opMacros[ordi].d2rMacro,0,7,64,uiColors[GUI_COLOR_MACRO_VOLUME]));
2023-10-17 18:24:57 -04:00
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DAM),&ins->std.opMacros[ordi].damMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DVB),&ins->std.opMacros[ordi].dvbMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.opMacros[ordi].susMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Op. Panning"),&ins->std.opMacros[ordi].rsMacro,0,2,40,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
2024-09-22 04:58:17 -04:00
} else if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_D2R),&ins->std.opMacros[ordi].d2rMacro,0,31,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RS),&ins->std.opMacros[ordi].rsMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DT),&ins->std.opMacros[ordi].dtMacro,0,7,64,uiColors[GUI_COLOR_MACRO_PITCH]));
2024-08-25 06:33:01 -04:00
if (ins->type==DIV_INS_OPM) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DT2),&ins->std.opMacros[ordi].dt2Macro,0,3,32,uiColors[GUI_COLOR_MACRO_PITCH]));
2022-09-24 02:33:36 -04:00
}
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
if (ins->type==DIV_INS_FM) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SSG),&ins->std.opMacros[ordi].ssgMacro,0,4,64,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,ssgEnvBits));
}
2024-09-22 04:58:17 -04:00
} else if (ins->type==DIV_INS_OPZ) {
2024-08-25 06:33:01 -04:00
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_VOLUME]));
2024-09-22 04:58:17 -04:00
if (ins->fm.op[ordi].egt) {
2024-08-25 06:33:01 -04:00
if (!ins->fm.op[ordi].sus) {
macroList.push_back(FurnaceGUIMacroDesc(_("Block"),&ins->std.opMacros[ordi].ssgMacro,0,7,64,uiColors[GUI_COLOR_MACRO_PITCH],true));
macroList.push_back(FurnaceGUIMacroDesc(_("FreqNum"),&ins->std.opMacros[ordi].susMacro,0,255,160,uiColors[GUI_COLOR_MACRO_PITCH]));
} else {
macroList.push_back(FurnaceGUIMacroDesc(_("Op. Arpeggio"),&ins->std.opMacros[ordi].ssgMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.opMacros[ordi].ssgMacro.val,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Op. Pitch"),&ins->std.opMacros[ordi].susMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode,NULL,false,NULL,false,NULL,false,true));
}
}
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_D2R),&ins->std.opMacros[ordi].d2rMacro,0,31,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RS),&ins->std.opMacros[ordi].rsMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DT),&ins->std.opMacros[ordi].dtMacro,0,7,64,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DT2),&ins->std.opMacros[ordi].dt2Macro,0,3,32,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
2022-02-28 18:16:05 -05:00
}
2025-03-10 13:46:46 -04:00
drawMacros(macroList,macroEditStateOP[ordi],ins);
2022-02-17 13:08:17 -05:00
ImGui::PopID();
ImGui::EndTabItem();
}
}
}
if (ins->type==DIV_INS_GB) if (ImGui::BeginTabItem("Game Boy")) {
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Use software envelope"),&ins->gb.softEnv));
P(ImGui::Checkbox(_("Initialize envelope on every note"),&ins->gb.alwaysInit));
P(ImGui::Checkbox(_("Double wave length (GBA only)"),&ins->gb.doubleWave));
2022-02-17 13:08:17 -05:00
ImGui::BeginDisabled(ins->gb.softEnv);
2022-08-17 19:29:40 -04:00
if (ImGui::BeginTable("GBParams",2)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.6f);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.4f);
2022-02-17 13:08:17 -05:00
2022-08-17 19:29:40 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginTable("GBParamsI",2)) {
ImGui::TableSetupColumn("ci0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("ci1",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Volume"));
2022-08-17 19:29:40 -04:00
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##GBVolume",ImGuiDataType_U8,&ins->gb.envVol,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Length"));
2022-08-17 19:29:40 -04:00
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
P(CWSliderScalar("##GBEnvLen",ImGuiDataType_U8,&ins->gb.envLen,&_ZERO,&_SEVEN)); rightClickable
2022-04-17 00:58:29 -04:00
2022-08-17 19:29:40 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Sound Length"));
2022-08-17 19:29:40 -04:00
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
2024-05-26 20:31:17 -04:00
P(CWSliderScalar("##GBSoundLen",ImGuiDataType_U8,&ins->gb.soundLen,&_ZERO,&_SIXTY_FOUR,ins->gb.soundLen>63?_("Infinity"):"%d")); rightClickable
2022-04-17 00:58:29 -04:00
2022-08-17 19:29:40 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Direction"));
2022-08-17 19:29:40 -04:00
ImGui::TableNextColumn();
bool goesUp=ins->gb.envDir;
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Up"),goesUp)) { PARAMETER
2022-08-17 19:29:40 -04:00
goesUp=true;
ins->gb.envDir=goesUp;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Down"),!goesUp)) { PARAMETER
2022-08-17 19:29:40 -04:00
goesUp=false;
ins->gb.envDir=goesUp;
}
ImGui::EndTable();
}
ImGui::TableNextColumn();
drawGBEnv(ins->gb.envVol,ins->gb.envLen,ins->gb.soundLen,ins->gb.envDir,ImVec2(ImGui::GetContentRegionAvail().x,100.0f*dpiScale));
ImGui::EndTable();
2022-02-17 13:08:17 -05:00
}
2022-04-17 00:58:29 -04:00
if (ImGui::BeginChild("HWSeq",ImGui::GetContentRegionAvail(),true,ImGuiWindowFlags_MenuBar)) {
ImGui::BeginMenuBar();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Hardware Sequence"));
ImGui::EndMenuBar();
if (ins->gb.hwSeqLen>0) if (ImGui::BeginTable("HWSeqList",3)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
int curFrame=0;
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Tick"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Command"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Move/Remove"));
for (int i=0; i<ins->gb.hwSeqLen; i++) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%d (#%d)",curFrame,i);
ImGui::TableNextColumn();
ImGui::PushID(i);
if (ins->gb.hwSeq[i].cmd>=DivInstrumentGB::DIV_GB_HWCMD_MAX) {
ins->gb.hwSeq[i].cmd=0;
}
int cmd=ins->gb.hwSeq[i].cmd;
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::Combo("##HWSeqCmd",&cmd,LocalizedComboGetter,gbHWSeqCmdTypes,DivInstrumentGB::DIV_GB_HWCMD_MAX)) {
if (ins->gb.hwSeq[i].cmd!=cmd) {
ins->gb.hwSeq[i].cmd=cmd;
ins->gb.hwSeq[i].data=0;
}
}
bool somethingChanged=false;
switch (ins->gb.hwSeq[i].cmd) {
case DivInstrumentGB::DIV_GB_HWCMD_ENVELOPE: {
int hwsVol=(ins->gb.hwSeq[i].data&0xf0)>>4;
bool hwsDir=ins->gb.hwSeq[i].data&8;
int hwsLen=ins->gb.hwSeq[i].data&7;
int hwsSoundLen=ins->gb.hwSeq[i].data>>8;
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Volume"),&hwsVol,0,15)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Env Length"),&hwsLen,0,7)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Sound Length"),&hwsSoundLen,0,64,hwsSoundLen>63?_("Infinity"):"%d")) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Up"),hwsDir)) { PARAMETER
hwsDir=true;
somethingChanged=true;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Down"),!hwsDir)) { PARAMETER
hwsDir=false;
somethingChanged=true;
}
if (somethingChanged) {
ins->gb.hwSeq[i].data=(hwsLen&7)|(hwsDir?8:0)|(hwsVol<<4)|(hwsSoundLen<<8);
PARAMETER;
}
break;
}
case DivInstrumentGB::DIV_GB_HWCMD_SWEEP: {
int hwsShift=ins->gb.hwSeq[i].data&7;
int hwsSpeed=(ins->gb.hwSeq[i].data&0x70)>>4;
bool hwsDir=ins->gb.hwSeq[i].data&8;
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Shift"),&hwsShift,0,7)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Speed"),&hwsSpeed,0,7)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Up"),!hwsDir)) { PARAMETER
hwsDir=false;
somethingChanged=true;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Down"),hwsDir)) { PARAMETER
hwsDir=true;
somethingChanged=true;
}
if (somethingChanged) {
ins->gb.hwSeq[i].data=(hwsShift&7)|(hwsDir?8:0)|(hwsSpeed<<4);
PARAMETER;
}
break;
}
case DivInstrumentGB::DIV_GB_HWCMD_WAIT: {
int len=ins->gb.hwSeq[i].data+1;
curFrame+=ins->gb.hwSeq[i].data+1;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Ticks"),&len,1,4)) {
if (len<1) len=1;
if (len>255) len=256;
somethingChanged=true;
}
if (somethingChanged) {
ins->gb.hwSeq[i].data=len-1;
PARAMETER;
}
break;
}
case DivInstrumentGB::DIV_GB_HWCMD_WAIT_REL:
curFrame++;
break;
case DivInstrumentGB::DIV_GB_HWCMD_LOOP:
case DivInstrumentGB::DIV_GB_HWCMD_LOOP_REL: {
int pos=ins->gb.hwSeq[i].data;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Position"),&pos,1,1)) {
if (pos<0) pos=0;
if (pos>(ins->gb.hwSeqLen-1)) pos=(ins->gb.hwSeqLen-1);
somethingChanged=true;
}
if (somethingChanged) {
ins->gb.hwSeq[i].data=pos;
PARAMETER;
}
break;
}
default:
break;
}
ImGui::PopID();
ImGui::TableNextColumn();
ImGui::PushID(i+512);
if (ImGui::Button(ICON_FA_CHEVRON_UP "##HWCmdUp")) {
if (i>0) {
e->lockEngine([ins,i]() {
ins->gb.hwSeq[i-1].cmd^=ins->gb.hwSeq[i].cmd;
ins->gb.hwSeq[i].cmd^=ins->gb.hwSeq[i-1].cmd;
ins->gb.hwSeq[i-1].cmd^=ins->gb.hwSeq[i].cmd;
ins->gb.hwSeq[i-1].data^=ins->gb.hwSeq[i].data;
ins->gb.hwSeq[i].data^=ins->gb.hwSeq[i-1].data;
ins->gb.hwSeq[i-1].data^=ins->gb.hwSeq[i].data;
});
}
MARK_MODIFIED;
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_CHEVRON_DOWN "##HWCmdDown")) {
if (i<ins->gb.hwSeqLen-1) {
e->lockEngine([ins,i]() {
2022-08-17 19:37:16 -04:00
ins->gb.hwSeq[i+1].cmd^=ins->gb.hwSeq[i].cmd;
ins->gb.hwSeq[i].cmd^=ins->gb.hwSeq[i+1].cmd;
ins->gb.hwSeq[i+1].cmd^=ins->gb.hwSeq[i].cmd;
2022-08-17 19:37:16 -04:00
ins->gb.hwSeq[i+1].data^=ins->gb.hwSeq[i].data;
ins->gb.hwSeq[i].data^=ins->gb.hwSeq[i+1].data;
ins->gb.hwSeq[i+1].data^=ins->gb.hwSeq[i].data;
});
}
MARK_MODIFIED;
}
ImGui::SameLine();
2023-08-26 08:09:27 -04:00
pushDestColor();
2023-08-27 02:18:39 -04:00
if (ImGui::Button(ICON_FA_TIMES "##HWCmdDel")) {
for (int j=i; j<ins->gb.hwSeqLen-1; j++) {
ins->gb.hwSeq[j].cmd=ins->gb.hwSeq[j+1].cmd;
ins->gb.hwSeq[j].data=ins->gb.hwSeq[j+1].data;
}
ins->gb.hwSeqLen--;
}
2023-08-26 08:09:27 -04:00
popDestColor();
ImGui::PopID();
}
ImGui::EndTable();
}
if (ImGui::Button(ICON_FA_PLUS "##HWCmdAdd")) {
if (ins->gb.hwSeqLen<255) {
ins->gb.hwSeq[ins->gb.hwSeqLen].cmd=0;
ins->gb.hwSeq[ins->gb.hwSeqLen].data=0;
ins->gb.hwSeqLen++;
}
}
}
ImGui::EndChild();
ImGui::EndDisabled();
2022-02-17 13:08:17 -05:00
ImGui::EndTabItem();
}
2024-04-21 13:38:59 -04:00
if (ins->type==DIV_INS_C64 || ins->type==DIV_INS_SID2) if (ImGui::BeginTabItem((ins->type==DIV_INS_SID2)?"SID2":"C64")) {
2023-08-07 01:47:17 -04:00
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Waveform"));
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.triOn);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("tri"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.triOn=!ins->c64.triOn;
}
popToggleColors();
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.sawOn);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("saw"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.sawOn=!ins->c64.sawOn;
}
popToggleColors();
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.pulseOn);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("pulse"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.pulseOn=!ins->c64.pulseOn;
}
popToggleColors();
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.noiseOn);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("noise"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.noiseOn=!ins->c64.noiseOn;
}
popToggleColors();
2022-02-17 13:08:17 -05:00
2022-04-17 03:51:03 -04:00
ImVec2 sliderSize=ImVec2(20.0f*dpiScale,128.0*dpiScale);
if (ImGui::BeginTable("C64EnvParams",5,ImGuiTableFlags_NoHostExtendX)) {
2022-04-17 03:51:03 -04:00
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
CENTER_TEXT("A");
ImGui::TextUnformatted("A");
ImGui::TableNextColumn();
CENTER_TEXT("D");
ImGui::TextUnformatted("D");
ImGui::TableNextColumn();
CENTER_TEXT("S");
ImGui::TextUnformatted("S");
ImGui::TableNextColumn();
CENTER_TEXT("R");
ImGui::TextUnformatted("R");
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("Envelope"));
ImGui::TextUnformatted(_("Envelope"));
2022-04-17 03:51:03 -04:00
ImGui::TableNextRow();
ImGui::TableNextColumn();
P(CWVSliderScalar("##Attack",sliderSize,ImGuiDataType_U8,&ins->c64.a,&_ZERO,&_FIFTEEN)); rightClickable
2022-04-17 03:51:03 -04:00
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay",sliderSize,ImGuiDataType_U8,&ins->c64.d,&_ZERO,&_FIFTEEN)); rightClickable
2022-04-17 03:51:03 -04:00
ImGui::TableNextColumn();
P(CWVSliderScalar("##Sustain",sliderSize,ImGuiDataType_U8,&ins->c64.s,&_ZERO,&_FIFTEEN)); rightClickable
2022-04-17 03:51:03 -04:00
ImGui::TableNextColumn();
P(CWVSliderScalar("##Release",sliderSize,ImGuiDataType_U8,&ins->c64.r,&_ZERO,&_FIFTEEN)); rightClickable
2022-04-17 03:51:03 -04:00
ImGui::TableNextColumn();
2024-04-21 13:38:59 -04:00
drawFMEnv((ins->type==DIV_INS_SID2)?(15-ins->sid2.volume):0,16-ins->c64.a,16-ins->c64.d,15-ins->c64.r,15-ins->c64.r,15-ins->c64.s,0,0,0,15,16,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type);
2022-04-17 03:51:03 -04:00
ImGui::EndTable();
}
2022-02-17 13:08:17 -05:00
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Duty"),ImGuiDataType_U16,&ins->c64.duty,&_ZERO,&_FOUR_THOUSAND_NINETY_FIVE)); rightClickable
2022-02-17 13:08:17 -05:00
bool resetDuty=ins->c64.resetDuty;
if (ImGui::Checkbox(_("Reset duty on new note"),&resetDuty)) { PARAMETER
ins->c64.resetDuty=resetDuty;
}
2022-02-17 13:08:17 -05:00
bool ringMod=ins->c64.ringMod;
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Ring Modulation"),&ringMod)) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.ringMod=ringMod;
}
bool oscSync=ins->c64.oscSync;
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Oscillator Sync"),&oscSync)) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.oscSync=oscSync;
}
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Enable filter"),&ins->c64.toFilter));
P(ImGui::Checkbox(_("Initialize filter"),&ins->c64.initFilter));
2022-02-17 13:08:17 -05:00
2024-04-22 07:21:13 -04:00
if (ins->type==DIV_INS_SID2) {
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Cutoff"),ImGuiDataType_U16,&ins->c64.cut,&_ZERO,&_FOUR_THOUSAND_NINETY_FIVE)); rightClickable
P(CWSliderScalar(_("Resonance"),ImGuiDataType_U8,&ins->c64.res,&_ZERO,&_TWO_HUNDRED_FIFTY_FIVE)); rightClickable
2024-04-22 07:21:13 -04:00
} else {
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Cutoff"),ImGuiDataType_U16,&ins->c64.cut,&_ZERO,&_TWO_THOUSAND_FORTY_SEVEN)); rightClickable
P(CWSliderScalar(_("Resonance"),ImGuiDataType_U8,&ins->c64.res,&_ZERO,&_FIFTEEN)); rightClickable
2024-04-22 07:21:13 -04:00
}
2022-02-17 13:08:17 -05:00
2023-08-07 01:47:17 -04:00
ImGui::AlignTextToFramePadding();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Filter Mode"));
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.lp);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("low"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.lp=!ins->c64.lp;
}
popToggleColors();
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.bp);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("band"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.bp=!ins->c64.bp;
}
popToggleColors();
2022-02-17 13:08:17 -05:00
ImGui::SameLine();
pushToggleColors(ins->c64.hp);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("high"))) { PARAMETER
2022-02-17 13:08:17 -05:00
ins->c64.hp=!ins->c64.hp;
}
popToggleColors();
2024-04-21 13:38:59 -04:00
if (ins->type!=DIV_INS_SID2) {
ImGui::SameLine();
pushToggleColors(ins->c64.ch3off);
2024-05-26 20:31:17 -04:00
if (ImGui::Button(_("ch3off"))) { PARAMETER
2024-04-21 13:38:59 -04:00
ins->c64.ch3off=!ins->c64.ch3off;
}
popToggleColors();
}
if (ins->type==DIV_INS_SID2) {
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Noise Mode"),ImGuiDataType_U8,&ins->sid2.noiseMode,&_ZERO,&_THREE));
P(CWSliderScalar(_("Wave Mix Mode"),ImGuiDataType_U8,&ins->sid2.mixMode,&_ZERO,&_THREE,sid2WaveMixModes[ins->sid2.mixMode&3]));
2022-02-17 13:08:17 -05:00
}
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Absolute Cutoff Macro"),&ins->c64.filterIsAbs)) {
ins->temp.vZoom[DIV_MACRO_ALG]=-1;
PARAMETER;
}
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Absolute Duty Macro"),&ins->c64.dutyIsAbs)) {
ins->temp.vZoom[DIV_MACRO_DUTY]=-1;
PARAMETER;
}
2024-04-21 13:38:59 -04:00
if (ins->type!=DIV_INS_SID2) {
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Don't test before new note"),&ins->c64.noTest));
2024-04-21 13:38:59 -04:00
}
2022-02-17 13:08:17 -05:00
ImGui::EndTabItem();
}
if (ins->type==DIV_INS_SU) if (ImGui::BeginTabItem("Sound Unit")) {
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Switch roles of frequency and phase reset timer"),&ins->su.switchRoles));
if (ImGui::BeginChild("HWSeqSU",ImGui::GetContentRegionAvail(),true,ImGuiWindowFlags_MenuBar)) {
ImGui::BeginMenuBar();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Hardware Sequence"));
ImGui::EndMenuBar();
if (ins->su.hwSeqLen>0) if (ImGui::BeginTable("HWSeqListSU",3)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed);
int curFrame=0;
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Tick"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Command"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Move/Remove"));
for (int i=0; i<ins->su.hwSeqLen; i++) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%d (#%d)",curFrame,i);
ImGui::TableNextColumn();
ImGui::PushID(i);
if (ins->su.hwSeq[i].cmd>=DivInstrumentSoundUnit::DIV_SU_HWCMD_MAX) {
ins->su.hwSeq[i].cmd=0;
}
int cmd=ins->su.hwSeq[i].cmd;
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::Combo("##HWSeqCmd",&cmd,LocalizedComboGetter,suHWSeqCmdTypes,DivInstrumentSoundUnit::DIV_SU_HWCMD_MAX)) {
if (ins->su.hwSeq[i].cmd!=cmd) {
ins->su.hwSeq[i].cmd=cmd;
ins->su.hwSeq[i].val=0;
ins->su.hwSeq[i].bound=0;
ins->su.hwSeq[i].speed=0;
}
}
bool somethingChanged=false;
switch (ins->su.hwSeq[i].cmd) {
case DivInstrumentSoundUnit::DIV_SU_HWCMD_VOL: {
int swPeriod=ins->su.hwSeq[i].speed;
int swBound=ins->su.hwSeq[i].bound;
int swVal=ins->su.hwSeq[i].val&31;
bool swDir=ins->su.hwSeq[i].val&32;
bool swLoop=ins->su.hwSeq[i].val&64;
bool swInvert=ins->su.hwSeq[i].val&128;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Period"),&swPeriod,1,16)) {
if (swPeriod<0) swPeriod=0;
if (swPeriod>65535) swPeriod=65535;
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Amount"),&swVal,0,31)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Bound"),&swBound,0,255)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Up"),swDir)) { PARAMETER
swDir=true;
somethingChanged=true;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Down"),!swDir)) { PARAMETER
swDir=false;
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Loop"),&swLoop)) { PARAMETER
somethingChanged=true;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Flip"),&swInvert)) { PARAMETER
somethingChanged=true;
}
if (somethingChanged) {
ins->su.hwSeq[i].speed=swPeriod;
ins->su.hwSeq[i].bound=swBound;
ins->su.hwSeq[i].val=(swVal&31)|(swDir?32:0)|(swLoop?64:0)|(swInvert?128:0);
PARAMETER;
}
break;
}
case DivInstrumentSoundUnit::DIV_SU_HWCMD_PITCH:
case DivInstrumentSoundUnit::DIV_SU_HWCMD_CUT: {
int swPeriod=ins->su.hwSeq[i].speed;
int swBound=ins->su.hwSeq[i].bound;
int swVal=ins->su.hwSeq[i].val&127;
bool swDir=ins->su.hwSeq[i].val&128;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Period"),&swPeriod,1,16)) {
if (swPeriod<0) swPeriod=0;
if (swPeriod>65535) swPeriod=65535;
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Amount"),&swVal,0,31)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (CWSliderInt(_("Bound"),&swBound,0,255)) {
somethingChanged=true;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Up"),swDir)) { PARAMETER
swDir=true;
somethingChanged=true;
}
ImGui::SameLine();
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Down"),!swDir)) { PARAMETER
swDir=false;
somethingChanged=true;
}
if (somethingChanged) {
ins->su.hwSeq[i].speed=swPeriod;
ins->su.hwSeq[i].bound=swBound;
ins->su.hwSeq[i].val=(swVal&127)|(swDir?128:0);
PARAMETER;
}
break;
}
case DivInstrumentSoundUnit::DIV_SU_HWCMD_WAIT: {
int len=ins->su.hwSeq[i].val+1;
curFrame+=ins->su.hwSeq[i].val+1;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Ticks"),&len)) {
if (len<1) len=1;
if (len>255) len=256;
somethingChanged=true;
}
if (somethingChanged) {
ins->su.hwSeq[i].val=len-1;
PARAMETER;
}
break;
}
case DivInstrumentSoundUnit::DIV_SU_HWCMD_WAIT_REL:
curFrame++;
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_LOOP:
case DivInstrumentSoundUnit::DIV_SU_HWCMD_LOOP_REL: {
int pos=ins->su.hwSeq[i].val;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Position"),&pos,1,4)) {
if (pos<0) pos=0;
if (pos>(ins->su.hwSeqLen-1)) pos=(ins->su.hwSeqLen-1);
somethingChanged=true;
}
if (somethingChanged) {
ins->su.hwSeq[i].val=pos;
PARAMETER;
}
break;
}
default:
break;
}
ImGui::PopID();
ImGui::TableNextColumn();
ImGui::PushID(i+512);
if (ImGui::Button(ICON_FA_CHEVRON_UP "##HWCmdUp")) {
if (i>0) {
e->lockEngine([ins,i]() {
ins->su.hwSeq[i-1].cmd^=ins->su.hwSeq[i].cmd;
ins->su.hwSeq[i].cmd^=ins->su.hwSeq[i-1].cmd;
ins->su.hwSeq[i-1].cmd^=ins->su.hwSeq[i].cmd;
ins->su.hwSeq[i-1].speed^=ins->su.hwSeq[i].speed;
ins->su.hwSeq[i].speed^=ins->su.hwSeq[i-1].speed;
ins->su.hwSeq[i-1].speed^=ins->su.hwSeq[i].speed;
ins->su.hwSeq[i-1].val^=ins->su.hwSeq[i].val;
ins->su.hwSeq[i].val^=ins->su.hwSeq[i-1].val;
ins->su.hwSeq[i-1].val^=ins->su.hwSeq[i].val;
ins->su.hwSeq[i-1].bound^=ins->su.hwSeq[i].bound;
ins->su.hwSeq[i].bound^=ins->su.hwSeq[i-1].bound;
ins->su.hwSeq[i-1].bound^=ins->su.hwSeq[i].bound;
});
}
MARK_MODIFIED;
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_CHEVRON_DOWN "##HWCmdDown")) {
if (i<ins->su.hwSeqLen-1) {
e->lockEngine([ins,i]() {
ins->su.hwSeq[i+1].cmd^=ins->su.hwSeq[i].cmd;
ins->su.hwSeq[i].cmd^=ins->su.hwSeq[i+1].cmd;
ins->su.hwSeq[i+1].cmd^=ins->su.hwSeq[i].cmd;
ins->su.hwSeq[i+1].speed^=ins->su.hwSeq[i].speed;
ins->su.hwSeq[i].speed^=ins->su.hwSeq[i+1].speed;
ins->su.hwSeq[i+1].speed^=ins->su.hwSeq[i].speed;
ins->su.hwSeq[i+1].val^=ins->su.hwSeq[i].val;
ins->su.hwSeq[i].val^=ins->su.hwSeq[i+1].val;
ins->su.hwSeq[i+1].val^=ins->su.hwSeq[i].val;
ins->su.hwSeq[i+1].bound^=ins->su.hwSeq[i].bound;
ins->su.hwSeq[i].bound^=ins->su.hwSeq[i+1].bound;
ins->su.hwSeq[i+1].bound^=ins->su.hwSeq[i].bound;
});
}
MARK_MODIFIED;
}
ImGui::SameLine();
pushDestColor();
if (ImGui::Button(ICON_FA_TIMES "##HWCmdDel")) {
for (int j=i; j<ins->su.hwSeqLen-1; j++) {
ins->su.hwSeq[j].cmd=ins->su.hwSeq[j+1].cmd;
ins->su.hwSeq[j].speed=ins->su.hwSeq[j+1].speed;
ins->su.hwSeq[j].val=ins->su.hwSeq[j+1].val;
ins->su.hwSeq[j].bound=ins->su.hwSeq[j+1].bound;
}
ins->su.hwSeqLen--;
}
popDestColor();
ImGui::PopID();
}
ImGui::EndTable();
}
if (ImGui::Button(ICON_FA_PLUS "##HWCmdAdd")) {
if (ins->su.hwSeqLen<255) {
ins->su.hwSeq[ins->su.hwSeqLen].cmd=0;
ins->su.hwSeq[ins->su.hwSeqLen].speed=0;
ins->su.hwSeq[ins->su.hwSeqLen].val=0;
ins->su.hwSeq[ins->su.hwSeqLen].bound=0;
ins->su.hwSeqLen++;
}
}
}
ImGui::EndChild();
ImGui::EndTabItem();
}
if (ins->type==DIV_INS_SID3) {
drawInsSID3(ins);
}
if (ins->type==DIV_INS_MSM6258 ||
ins->type==DIV_INS_MSM6295 ||
ins->type==DIV_INS_ADPCMA ||
ins->type==DIV_INS_ADPCMB ||
ins->type==DIV_INS_SEGAPCM ||
ins->type==DIV_INS_QSOUND ||
ins->type==DIV_INS_YMZ280B ||
ins->type==DIV_INS_RF5C68 ||
ins->type==DIV_INS_AMIGA ||
ins->type==DIV_INS_MULTIPCM ||
ins->type==DIV_INS_SU ||
ins->type==DIV_INS_SNES ||
ins->type==DIV_INS_ES5506 ||
2022-12-15 06:03:54 -05:00
ins->type==DIV_INS_K007232 ||
2023-04-02 01:32:47 -04:00
ins->type==DIV_INS_GA20 ||
2023-08-09 07:30:00 -04:00
ins->type==DIV_INS_K053260 ||
ins->type==DIV_INS_C140 ||
2024-01-09 23:17:36 -05:00
ins->type==DIV_INS_C219 ||
2024-03-17 16:44:38 -04:00
ins->type==DIV_INS_NDS ||
2024-03-16 03:59:02 -04:00
ins->type==DIV_INS_GBA_DMA ||
ins->type==DIV_INS_GBA_MINMOD ||
ins->type==DIV_INS_SUPERVISION) {
insTabSample(ins);
2022-02-17 13:08:17 -05:00
}
2023-07-20 17:50:19 -04:00
if (ins->type==DIV_INS_N163) if (ImGui::BeginTabItem("Namco 163")) {
2023-07-20 19:23:58 -04:00
bool preLoad=ins->n163.waveMode&0x1;
2024-05-26 20:31:17 -04:00
if (ImGui::Checkbox(_("Load waveform"),&preLoad)) { PARAMETER
2023-07-20 19:23:58 -04:00
ins->n163.waveMode=(ins->n163.waveMode&~0x1)|(preLoad?0x1:0);
}
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("when enabled, a waveform will be loaded into RAM.\nwhen disabled, only the offset and length change."));
2023-07-20 19:23:58 -04:00
}
if (preLoad) {
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Waveform##WAVE"),&ins->n163.wave,1,10)) { PARAMETER
2023-07-20 19:23:58 -04:00
if (ins->n163.wave<0) ins->n163.wave=0;
if (ins->n163.wave>=e->song.waveLen) ins->n163.wave=e->song.waveLen-1;
}
}
ImGui::Separator();
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Per-channel wave position/length"),&ins->n163.perChanPos));
if (ins->n163.perChanPos) {
if (ImGui::BeginTable("N1PerChPos",3)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5f);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.5f);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Ch"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Position"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Length"));
for (int i=0; i<8; i++) {
ImGui::PushID(64+i);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(dpiScale,ImGui::GetFrameHeightWithSpacing()));
ImGui::SameLine();
ImGui::Text("%d",i+1);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##pcOff",&ins->n163.wavePosCh[i],1,16)) { PARAMETER
if (ins->n163.wavePosCh[i]<0) ins->n163.wavePosCh[i]=0;
if (ins->n163.wavePosCh[i]>255) ins->n163.wavePosCh[i]=255;
}
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##pcLen",&ins->n163.waveLenCh[i],4,16)) { PARAMETER
if (ins->n163.waveLenCh[i]<0) ins->n163.waveLenCh[i]=0;
if (ins->n163.waveLenCh[i]>252) ins->n163.waveLenCh[i]=252;
ins->n163.waveLenCh[i]&=0xfc;
}
ImGui::PopID();
}
ImGui::EndTable();
}
} else {
2023-07-29 14:43:49 -04:00
if (ImGui::InputInt("Position##WAVEPOS",&ins->n163.wavePos,1,16)) { PARAMETER
if (ins->n163.wavePos<0) ins->n163.wavePos=0;
if (ins->n163.wavePos>255) ins->n163.wavePos=255;
}
if (ImGui::InputInt("Length##WAVELEN",&ins->n163.waveLen,4,16)) { PARAMETER
if (ins->n163.waveLen<0) ins->n163.waveLen=0;
if (ins->n163.waveLen>252) ins->n163.waveLen=252;
ins->n163.waveLen&=0xfc;
}
}
ImGui::EndTabItem();
}
2022-04-04 14:26:02 -04:00
if (ins->type==DIV_INS_FDS) if (ImGui::BeginTabItem("FDS")) {
float modTable[32];
int modTableInt[256];
2024-05-26 20:31:17 -04:00
ImGui::Checkbox(_("Compatibility mode"),&ins->fds.initModTableWithFirstWave);
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("only use for compatibility with .dmf modules!\n- initializes modulation table with first wavetable\n- does not alter modulation parameters on instrument change"));
}
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Modulation depth"),&ins->fds.modDepth,1,4)) {
2022-04-05 15:55:17 -04:00
if (ins->fds.modDepth<0) ins->fds.modDepth=0;
if (ins->fds.modDepth>63) ins->fds.modDepth=63;
}
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Modulation speed"),&ins->fds.modSpeed,1,4)) {
2022-04-05 15:55:17 -04:00
if (ins->fds.modSpeed<0) ins->fds.modSpeed=0;
if (ins->fds.modSpeed>4095) ins->fds.modSpeed=4095;
}
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Modulation table"));
for (int i=0; i<32; i++) {
modTable[i]=ins->fds.modTable[i];
modTableInt[i]=ins->fds.modTable[i];
}
ImVec2 modTableSize=ImVec2(ImGui::GetContentRegionAvail().x,96.0f*dpiScale);
2022-09-09 17:41:00 -04:00
PlotCustom("ModTable",modTable,32,0,NULL,-4,3,modTableSize,sizeof(float),ImVec4(1.0f,1.0f,1.0f,1.0f),0,NULL,NULL,true);
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
macroDragStart=ImGui::GetItemRectMin();
macroDragAreaSize=modTableSize;
macroDragMin=-4;
macroDragMax=3;
macroDragBitMode=false;
macroDragInitialValueSet=false;
macroDragInitialValue=false;
macroDragLen=32;
macroDragActive=true;
macroDragCTarget=(unsigned char*)ins->fds.modTable;
macroDragChar=true;
2022-04-13 00:03:20 -04:00
macroDragLineMode=false;
macroDragLineInitial=ImVec2(0,0);
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
ImGui::InhibitInertialScroll();
}
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); // wavetable text input size found here
if (ImGui::InputText("##MMLModTable",&mmlStringModTable)) {
int discardIt=0;
memset(modTableInt,0,256*sizeof(int));
decodeMMLStrW(mmlStringModTable,modTableInt,discardIt,-4,3,false);
for (int i=0; i<32; i++) {
if (i>=discardIt) {
modTableInt[i]=0;
} else {
if (modTableInt[i]<-4) modTableInt[i]=-4;
if (modTableInt[i]>3) modTableInt[i]=3;
}
ins->fds.modTable[i]=modTableInt[i];
}
MARK_MODIFIED;
}
if (!ImGui::IsItemActive()) {
encodeMMLStr(mmlStringModTable,modTableInt,32,-1,-1,false);
}
2022-04-04 14:26:02 -04:00
ImGui::EndTabItem();
}
2022-10-10 23:17:31 -04:00
if (ins->type==DIV_INS_VBOY) if (ImGui::BeginTabItem("Virtual Boy")) {
float modTable[32];
int modTableInt[256];
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Set modulation table (channel 5 only)"),&ins->fds.initModTableWithFirstWave));
2022-10-10 23:17:31 -04:00
ImGui::BeginDisabled(!ins->fds.initModTableWithFirstWave);
for (int i=0; i<32; i++) {
modTable[i]=ins->fds.modTable[i];
modTableInt[i]=modTableHex?((unsigned char)ins->fds.modTable[i]):ins->fds.modTable[i];
2022-10-10 23:17:31 -04:00
}
ImVec2 modTableSize=ImVec2(ImGui::GetContentRegionAvail().x,256.0f*dpiScale);
PlotCustom("ModTable",modTable,32,0,NULL,-128,127,modTableSize,sizeof(float),ImVec4(1.0f,1.0f,1.0f,1.0f),0,NULL,NULL,true);
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
macroDragStart=ImGui::GetItemRectMin();
macroDragAreaSize=modTableSize;
macroDragMin=-128;
macroDragMax=127;
macroDragBitMode=false;
macroDragInitialValueSet=false;
macroDragInitialValue=false;
macroDragLen=32;
macroDragActive=true;
macroDragCTarget=(unsigned char*)ins->fds.modTable;
macroDragChar=true;
macroDragLineMode=false;
macroDragLineInitial=ImVec2(0,0);
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
ImGui::InhibitInertialScroll();
2022-10-10 23:17:31 -04:00
}
if (ImGui::Button(modTableHex?"Hex##MTHex":"Dec##MTHex")) {
modTableHex=!modTableHex;
}
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); // wavetable text input size found here
if (ImGui::InputText("##MMLModTable",&mmlStringModTable)) {
int discardIt=0;
memset(modTableInt,0,256*sizeof(int));
decodeMMLStrW(mmlStringModTable,modTableInt,discardIt,modTableHex?0:-128,modTableHex?255:127,modTableHex);
for (int i=0; i<32; i++) {
if (i>=discardIt) {
modTableInt[i]=0;
} else {
if (modTableInt[i]>=128) modTableInt[i]-=256;
}
ins->fds.modTable[i]=modTableInt[i];
}
MARK_MODIFIED;
}
if (!ImGui::IsItemActive()) {
encodeMMLStr(mmlStringModTable,modTableInt,32,-1,-1,modTableHex);
}
ImGui::SameLine();
2022-10-10 23:17:31 -04:00
ImGui::EndDisabled();
ImGui::EndTabItem();
}
if (ins->type==DIV_INS_ES5506) if (ImGui::BeginTabItem("ES5506")) {
if (ImGui::BeginTable("ESParams",2,ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0);
// filter
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Filter Mode"),ImGuiDataType_U8,&ins->es5506.filter.mode,&_ZERO,&_THREE,es5506FilterModes[ins->es5506.filter.mode&3]));
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Filter K1"),ImGuiDataType_U16,&ins->es5506.filter.k1,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Filter K2"),ImGuiDataType_U16,&ins->es5506.filter.k2,&_ZERO,&_SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE)); rightClickable
// envelope
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Envelope length"),ImGuiDataType_U16,&ins->es5506.envelope.ecount,&_ZERO,&_FIVE_HUNDRED_ELEVEN)); rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Left Volume Ramp"),ImGuiDataType_S8,&ins->es5506.envelope.lVRamp,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Right Volume Ramp"),ImGuiDataType_S8,&ins->es5506.envelope.rVRamp,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Filter K1 Ramp"),ImGuiDataType_S8,&ins->es5506.envelope.k1Ramp,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("Filter K2 Ramp"),ImGuiDataType_S8,&ins->es5506.envelope.k2Ramp,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Checkbox(_("K1 Ramp Slowdown"),&ins->es5506.envelope.k1Slow);
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
ImGui::Checkbox(_("K2 Ramp Slowdown"),&ins->es5506.envelope.k2Slow);
ImGui::EndTable();
}
ImGui::EndTabItem();
}
if (ins->type==DIV_INS_MULTIPCM) {
if (ImGui::BeginTabItem("MultiPCM")) {
ImVec2 sliderSize=ImVec2(20.0f*dpiScale,128.0*dpiScale);
if (ImGui::BeginTable("MultiPCMADSRParams",7,ImGuiTableFlags_NoHostExtendX)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c6",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
CENTER_TEXT("AR");
ImGui::TextUnformatted("AR");
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Attack Rate"));
}
ImGui::TableNextColumn();
CENTER_TEXT("D1R");
ImGui::TextUnformatted("D1R");
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Decay 1 Rate"));
}
ImGui::TableNextColumn();
CENTER_TEXT("DL");
ImGui::TextUnformatted("DL");
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Decay Level"));
}
ImGui::TableNextColumn();
CENTER_TEXT("D2R");
ImGui::TextUnformatted("D2R");
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Decay 2 Rate"));
}
ImGui::TableNextColumn();
CENTER_TEXT("RR");
ImGui::TextUnformatted("RR");
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Release Rate"));
}
ImGui::TableNextColumn();
CENTER_TEXT("RC");
ImGui::TextUnformatted("RC");
if (ImGui::IsItemHovered()) {
2024-05-26 20:31:17 -04:00
ImGui::SetTooltip(_("Rate Correction"));
}
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("Envelope"));
ImGui::TextUnformatted(_("Envelope"));
ImGui::TableNextRow();
ImGui::TableNextColumn();
P(CWVSliderScalar("##Attack Rate",sliderSize,ImGuiDataType_U8,&ins->multipcm.ar,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay 1 Rate",sliderSize,ImGuiDataType_U8,&ins->multipcm.d1r,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay Level",sliderSize,ImGuiDataType_U8,&ins->multipcm.dl,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay 2 Rate",sliderSize,ImGuiDataType_U8,&ins->multipcm.d2r,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Release Rate",sliderSize,ImGuiDataType_U8,&ins->multipcm.rr,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Rate Correction",sliderSize,ImGuiDataType_U8,&ins->multipcm.rc,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
2022-09-28 20:33:16 -04:00
drawFMEnv(0,ins->multipcm.ar,ins->multipcm.d1r,ins->multipcm.d2r,ins->multipcm.rr,ins->multipcm.dl,0,0,0,127,15,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type);
ImGui::EndTable();
}
if (ImGui::BeginTable("MultiPCMLFOParams",3,ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.0);
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("LFO Rate"),ImGuiDataType_U8,&ins->multipcm.lfo,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("PM Depth"),ImGuiDataType_U8,&ins->multipcm.vib,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
P(CWSliderScalar(_("AM Depth"),ImGuiDataType_U8,&ins->multipcm.am,&_ZERO,&_SEVEN)); rightClickable
ImGui::EndTable();
}
P(ImGui::Checkbox(_("Damp"),&ins->multipcm.damp));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Only for OPL4 PCM."));
}
P(ImGui::Checkbox(_("Pseudo Reverb"),&ins->multipcm.pseudoReverb));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Only for OPL4 PCM."));
}
P(ImGui::Checkbox(_("LFO Reset"),&ins->multipcm.lfoReset));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Only for OPL4 PCM."));
}
2024-10-09 05:40:24 -04:00
P(ImGui::Checkbox(_("Disable volume change ramp"),&ins->multipcm.levelDirect));
ImGui::EndTabItem();
}
}
2022-08-19 20:42:01 -04:00
if (ins->type==DIV_INS_SNES) if (ImGui::BeginTabItem("SNES")) {
2024-05-26 20:31:17 -04:00
P(ImGui::Checkbox(_("Use envelope"),&ins->snes.useEnv));
2022-08-19 20:42:01 -04:00
ImVec2 sliderSize=ImVec2(20.0f*dpiScale,128.0*dpiScale);
if (ins->snes.useEnv) {
if (ImGui::BeginTable("SNESEnvParams",ins->snes.sus?6:5,ImGuiTableFlags_NoHostExtendX)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
if (ins->snes.sus) {
ImGui::TableSetupColumn("c2x",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
}
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
CENTER_TEXT("A");
ImGui::TextUnformatted("A");
ImGui::TableNextColumn();
CENTER_TEXT("D");
ImGui::TextUnformatted("D");
ImGui::TableNextColumn();
CENTER_TEXT("S");
ImGui::TextUnformatted("S");
if (ins->snes.sus) {
ImGui::TableNextColumn();
CENTER_TEXT("D2");
ImGui::TextUnformatted("D2");
}
ImGui::TableNextColumn();
CENTER_TEXT("R");
ImGui::TextUnformatted("R");
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("Envelope"));
ImGui::TextUnformatted(_("Envelope"));
ImGui::TableNextRow();
ImGui::TableNextColumn();
P(CWVSliderScalar("##Attack",sliderSize,ImGuiDataType_U8,&ins->snes.a,&_ZERO,&_FIFTEEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay",sliderSize,ImGuiDataType_U8,&ins->snes.d,&_ZERO,&_SEVEN)); rightClickable
ImGui::TableNextColumn();
P(CWVSliderScalar("##Sustain",sliderSize,ImGuiDataType_U8,&ins->snes.s,&_ZERO,&_SEVEN)); rightClickable
if (ins->snes.sus) {
ImGui::TableNextColumn();
P(CWVSliderScalar("##Decay2",sliderSize,ImGuiDataType_U8,&ins->snes.d2,&_ZERO,&_THIRTY_ONE)); rightClickable
}
ImGui::TableNextColumn();
P(CWVSliderScalar("##Release",sliderSize,ImGuiDataType_U8,&ins->snes.r,&_ZERO,&_THIRTY_ONE)); rightClickable
ImGui::TableNextColumn();
drawFMEnv(0,ins->snes.a+1,1+ins->snes.d*2,ins->snes.sus?ins->snes.d2:ins->snes.r,ins->snes.sus?ins->snes.r:31,(14-ins->snes.s*2),(ins->snes.r==0 || (ins->snes.sus && ins->snes.d2==0)),0,0,7,16,31,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type);
ImGui::EndTable();
}
2024-05-26 20:31:17 -04:00
ImGui::Text(_("Sustain/release mode:"));
if (ImGui::RadioButton(_("Direct (cut on release)"),ins->snes.sus==0)) {
ins->snes.sus=0;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Effective (linear decrease)"),ins->snes.sus==1)) {
ins->snes.sus=1;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Effective (exponential decrease)"),ins->snes.sus==2)) {
ins->snes.sus=2;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Delayed (write R on release)"),ins->snes.sus==3)) {
ins->snes.sus=3;
}
} else {
2023-08-24 15:52:18 -04:00
if (ImGui::BeginTable("SNESGainParams",2,ImGuiTableFlags_NoHostExtendX)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("Gain Mode"));
ImGui::TextUnformatted(_("Gain Mode"));
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
CENTER_TEXT(_("Gain"));
ImGui::TextUnformatted(_("Gain"));
ImGui::TableNextRow();
ImGui::TableNextColumn();
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Direct"),ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT)) {
ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_DIRECT;
PARAMETER;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Decrease (linear)"),ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LINEAR)) {
ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_DEC_LINEAR;
PARAMETER;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Decrease (logarithmic)"),ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LOG)) {
ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_DEC_LOG;
PARAMETER;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Increase (linear)"),ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_INC_LINEAR)) {
ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_INC_LINEAR;
PARAMETER;
}
2024-05-26 20:31:17 -04:00
if (ImGui::RadioButton(_("Increase (bent line)"),ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_INC_INVLOG)) {
ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_INC_INVLOG;
PARAMETER;
}
ImGui::TableNextColumn();
unsigned char gainMax=(ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT)?127:31;
if (ins->snes.gain>gainMax) ins->snes.gain=gainMax;
P(CWVSliderScalar("##Gain",sliderSize,ImGuiDataType_U8,&ins->snes.gain,&_ZERO,&gainMax)); rightClickable
ImGui::EndTable();
}
2023-08-24 15:52:18 -04:00
if (ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LINEAR || ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LOG) {
2024-05-26 20:31:17 -04:00
ImGui::TextWrapped(_("using decrease modes will not produce any sound at all, unless you know what you are doing.\nit is recommended to use the Gain macro for decrease instead."));
2023-08-24 15:52:18 -04:00
}
}
ImGui::EndTabItem();
}
2022-04-07 19:27:17 -04:00
if (ins->type==DIV_INS_GB ||
(ins->type==DIV_INS_AMIGA && ins->amiga.useWave) ||
2024-01-09 23:17:36 -05:00
(ins->type==DIV_INS_GBA_DMA && ins->amiga.useWave) ||
(ins->type==DIV_INS_X1_010 && !ins->amiga.useSample) ||
2022-04-07 19:27:17 -04:00
ins->type==DIV_INS_N163 ||
ins->type==DIV_INS_FDS ||
(ins->type==DIV_INS_SWAN && !ins->amiga.useSample) ||
(ins->type==DIV_INS_PCE && !ins->amiga.useSample) ||
2022-10-09 00:25:15 -04:00
(ins->type==DIV_INS_VBOY) ||
ins->type==DIV_INS_SCC ||
ins->type==DIV_INS_SNES ||
2023-02-11 07:56:41 -05:00
ins->type==DIV_INS_NAMCO ||
2024-03-16 03:59:02 -04:00
ins->type==DIV_INS_SM8521 ||
(ins->type==DIV_INS_GBA_MINMOD && ins->amiga.useWave))
{
insTabWavetable(ins);
2022-04-07 19:27:17 -04:00
}
2024-05-26 20:31:17 -04:00
if (ins->type<DIV_INS_MAX) if (ImGui::BeginTabItem(_("Macros"))) {
// NEW CODE
// this is only the first part of an insEdit refactor.
// don't complain yet!
int waveCount=MAX(1,e->song.waveLen-1);
switch (ins->type) {
case DIV_INS_STD:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Mode"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_FM:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_GB:
if (ins->gb.softEnv) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Noise"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_C64:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,4095,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,4,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,c64ShapeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Cutoff"),&ins->std.algMacro,ins->c64.filterIsAbs?0:-2047,2047,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Resonance"),&ins->std.ex2Macro,0,15,64,uiColors[GUI_COLOR_MACRO_FILTER]));
2024-07-05 18:03:01 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Mode"),&ins->std.ex1Macro,0,4,64,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true,filtModeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Toggle"),&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Special"),&ins->std.ex4Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c64TestGateBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Attack"),&ins->std.ex5Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Decay"),&ins->std.ex6Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Sustain"),&ins->std.ex7Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Release"),&ins->std.ex8Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
break;
case DIV_INS_AMIGA:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,64,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
if (ins->std.panLMacro.mode) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-16,16,63,uiColors[GUI_COLOR_MACRO_OTHER],false,macroQSoundMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Surround"),&ins->std.panRMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
} else {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER],false,macroQSoundMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER]));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_PCE:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_NOISE]));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_AY:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Freq"),&ins->std.dutyMacro,0,31,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-08-16 10:55:40 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,3,48,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,ayShapeBits));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope"),&ins->std.ex2Macro,0,4,64,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,ayEnvBits));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Num"),&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Den"),&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Force Period"),&ins->std.ex4Macro,0,4095,160,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(_("Env Period"),&ins->std.ex5Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
break;
case DIV_INS_AY8930:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Freq"),&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,3,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,ayShapeBits));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.ex1Macro,0,8,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope"),&ins->std.ex2Macro,0,4,64,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,ayEnvBits));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Num"),&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Den"),&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Force Period"),&ins->std.ex4Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(_("Env Period"),&ins->std.ex5Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise AND Mask"),&ins->std.fbMacro,0,8,96,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise OR Mask"),&ins->std.fmsMacro,0,8,96,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
break;
case DIV_INS_TIA:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,15,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_SAA1099:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Noise"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,2,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,ayShapeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope"),&ins->std.ex1Macro,0,8,160,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,saaEnvBits));
break;
case DIV_INS_VIC:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("On/Off"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,15,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_PET:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,8,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_VRC6:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.dutyMacro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER]));
} else {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
if (ins->amiga.useSample) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
}
break;
case DIV_INS_OPLL:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Patch"),&ins->std.waveMacro,0,15,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_OPL:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,4,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_FDS:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,32,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Mod Depth"),&ins->std.ex1Macro,0,63,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Mod Speed"),&ins->std.ex2Macro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Mod Position"),&ins->std.ex3Macro,0,127,160,uiColors[GUI_COLOR_MACRO_OTHER]));
break;
case DIV_INS_VBOY:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Length"),&ins->std.dutyMacro,0,7,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_N163:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Pos"),&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Length"),&ins->std.ex1Macro,0,252,160,uiColors[GUI_COLOR_MACRO_OTHER]));
break;
case DIV_INS_SCC:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_OPZ:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Freq"),&ins->std.dutyMacro,0,32,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_POKEY:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("AUDCTL"),&ins->std.dutyMacro,0,8,160,uiColors[GUI_COLOR_MACRO_GLOBAL],false,NULL,NULL,true,pokeyCtlBits));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,7,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_BEEPER: {
bool zxPresent=false;
for (int i=0; i<e->song.systemLen; i++) {
if (e->song.system[i]==DIV_SYSTEM_SFX_BEEPER) {
zxPresent=true;
break;
}
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (zxPresent) {
macroList.push_back(FurnaceGUIMacroDesc(_("Pulse Width"),&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
}
case DIV_INS_SWAN:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise"),&ins->std.dutyMacro,0,8,160,uiColors[GUI_COLOR_MACRO_NOISE]));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
2024-08-23 21:10:23 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_MIKEY:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Int"),&ins->std.dutyMacro,0,10,160,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true,mikeyFeedbackBits));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Load LFSR"),&ins->std.ex1Macro,0,12,160,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
break;
case DIV_INS_VERA:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.dutyMacro,0,63,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,3,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,macroVERAWaves,false,NULL));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_X1_010:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
if (ins->amiga.useSample) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
} else {
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope Mode"),&ins->std.ex1Macro,0,7,160,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,x1_010EnvBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope"),&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,false,ayEnvBits));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Num"),&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Den"),&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
}
break;
case DIV_INS_VRC6_SAW:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
2024-06-24 03:44:17 -04:00
case DIV_INS_ES5506: {
float usesAmigaVol=true;
for (int i=0; i<e->song.systemLen; i++) {
if (e->song.system[i]==DIV_SYSTEM_ES5506) {
if (!e->song.systemFlags[i].getBool("amigaVol",false)) {
usesAmigaVol=false;
break;
}
}
}
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,usesAmigaVol?64:4095,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Mode"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,&macroHoverES5506FilterMode));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter K1"),&ins->std.ex1Macro,((ins->std.ex1Macro.mode==1)?(-65535):0),65535,160,uiColors[GUI_COLOR_MACRO_FILTER],false,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter K2"),&ins->std.ex2Macro,((ins->std.ex2Macro.mode==1)?(-65535):0),65535,160,uiColors[GUI_COLOR_MACRO_FILTER],false,macroRelativeMode));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Outputs"),&ins->std.fbMacro,0,5,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Control"),&ins->std.algMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506ControlModes));
break;
2024-06-24 03:44:17 -04:00
}
case DIV_INS_MULTIPCM:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-7,7,45,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
2024-07-13 19:31:28 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Speed"),&ins->std.ex1Macro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Vib Depth"),&ins->std.fmsMacro,0,7,160,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(_("LFO AM Depth"),&ins->std.amsMacro,0,7,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
break;
case DIV_INS_SNES:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Freq"),&ins->std.dutyMacro,0,31,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Special"),&ins->std.ex1Macro,0,5,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,snesModeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Gain"),&ins->std.ex2Macro,0,255,256,uiColors[GUI_COLOR_MACRO_VOLUME],false,NULL,macroHoverGain,false));
break;
case DIV_INS_SU:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Noise"),&ins->std.dutyMacro,0,127,160,uiColors[GUI_COLOR_MACRO_NOISE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,7,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,macroSoundUnitWaves,false,NULL));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-127,127,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Cutoff"),&ins->std.ex1Macro,0,16383,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Resonance"),&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Control"),&ins->std.ex3Macro,0,4,64,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true,suControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset Timer"),&ins->std.ex4Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_PITCH])); // again reuse code from resonance macro but use ex4 instead
break;
case DIV_INS_NAMCO:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_OPL_DRUMS:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,4,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_OPM:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Freq"),&ins->std.dutyMacro,0,32,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_NES:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Noise"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_MSM6258:
macroList.push_back(FurnaceGUIMacroDesc(_("Freq Divider"),&ins->std.dutyMacro,0,2,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Clock Divider"),&ins->std.ex1Macro,0,1,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
break;
case DIV_INS_MSM6295:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,8,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Freq Divider"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_ADPCMA:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Global Volume"),&ins->std.dutyMacro,0,63,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_ADPCMB:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_SEGAPCM:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_QSOUND:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,16383,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Echo Level"),&ins->std.dutyMacro,0,32767,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-16,16,63,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Surround"),&ins->std.panRMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Echo Feedback"),&ins->std.ex1Macro,0,16383,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
macroList.push_back(FurnaceGUIMacroDesc(_("Echo Length"),&ins->std.ex2Macro,0,2725,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
break;
case DIV_INS_YMZ280B:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-7,7,45,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_RF5C68:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_MSM5232:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Group Ctrl"),&ins->std.dutyMacro,0,5,160,uiColors[GUI_COLOR_MACRO_GLOBAL],false,NULL,NULL,true,msm5232ControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Group Attack"),&ins->std.ex1Macro,0,5,96,uiColors[GUI_COLOR_MACRO_GLOBAL]));
macroList.push_back(FurnaceGUIMacroDesc(_("Group Decay"),&ins->std.ex2Macro,0,11,160,uiColors[GUI_COLOR_MACRO_GLOBAL]));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise"),&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
break;
case DIV_INS_T6W28:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Type"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_K007232:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_GA20:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_POKEMINI:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,2,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Pulse Width"),&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
2024-08-08 15:58:01 -04:00
case DIV_INS_SUPERVISION:
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Noise"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-09-05 20:24:42 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Noise/PCM Pan"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
2024-08-08 15:58:01 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_SM8521:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_PV1000:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
case DIV_INS_K053260:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-3,3,37,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_TED:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,8,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Square/Noise"),&ins->std.dutyMacro,0,2,80,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true,tedControlBits));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_C140:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_C219:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Control"),&ins->std.dutyMacro,0,3,120,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c219ControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_ESFM:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("OP4 Noise Mode"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_POWERNOISE:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Control"),&ins->std.ex1Macro,0,2,32,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true,powerNoiseControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Tap A Location"),&ins->std.ex4Macro,0,15,96,uiColors[GUI_COLOR_MACRO_NOISE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Tap B Location"),&ins->std.ex5Macro,0,15,96,uiColors[GUI_COLOR_MACRO_NOISE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Load LFSR"),&ins->std.ex8Macro,0,16,256,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
break;
case DIV_INS_POWERNOISE_SLOPE:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Control"),&ins->std.ex1Macro,0,6,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,powerNoiseSlopeControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Portion A Length"),&ins->std.ex2Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Portion B Length"),&ins->std.ex3Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Portion A Offset"),&ins->std.ex6Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Portion B Offset"),&ins->std.ex7Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER]));
break;
case DIV_INS_DAVE:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Freq"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,4,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,63,94,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,63,94,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Control"),&ins->std.ex1Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,daveControlBits));
break;
case DIV_INS_NDS:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
if (!ins->amiga.useSample) {
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.dutyMacro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER]));
}
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-64,63,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_GBA_DMA:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,2,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
break;
case DIV_INS_GBA_MINMOD:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Special"),&ins->std.ex1Macro,0,2,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,minModModeBits));
break;
case DIV_INS_BIFURCATOR:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Parameter"),&ins->std.dutyMacro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Load Value"),&ins->std.ex1Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER]));
break;
case DIV_INS_SID2:
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,4095,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,4,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,c64ShapeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Cutoff"),&ins->std.algMacro,ins->c64.filterIsAbs?0:-4095,4095,160,uiColors[GUI_COLOR_MACRO_FILTER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Resonance"),&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_FILTER]));
2024-07-05 18:03:01 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Mode"),&ins->std.ex1Macro,0,3,64,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true,filtModeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Filter Toggle"),&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_FILTER],false,NULL,NULL,true));
2024-05-26 20:31:17 -04:00
macroList.push_back(FurnaceGUIMacroDesc(_("Special"),&ins->std.ex4Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,sid2ControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Attack"),&ins->std.ex5Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Decay"),&ins->std.ex6Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Sustain"),&ins->std.ex7Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Release"),&ins->std.ex8Macro,0,15,128,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Mode"),&ins->std.fmsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_NOISE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Mix"),&ins->std.amsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroSID2WaveMixMode));
break;
2024-08-11 02:22:49 -04:00
case DIV_INS_UPD1771C:
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,7,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Pos"),&ins->std.ex1Macro,0,31,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Mode"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_NOISE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
break;
2024-09-14 00:46:03 -04:00
case DIV_INS_SID3:
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
if (ins->sid3.doWavetable) {
int waveCount=MAX(1,e->song.waveLen-1);
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
} else {
macroList.push_back(FurnaceGUIMacroDesc(_("Duty"),&ins->std.dutyMacro,ins->sid3.dutyIsAbs?0:-65535,65535,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,5,16 * 5,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,sid3ShapeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Special Wave"),&ins->std.algMacro,0,SID3_NUM_SPECIAL_WAVES - 1,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,macroSID3SpecialWaves));
}
if (ins->sid3.separateNoisePitch && !ins->sid3.doWavetable) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Arpeggio"),&ins->std.opMacros[3].amMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.opMacros[3].amMacro.val,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Pitch"),&ins->std.opMacros[0].arMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode,NULL,false,NULL,false,NULL,false,true));
}
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (left)"),&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
macroList.push_back(FurnaceGUIMacroDesc(_("Panning (right)"),&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Channel inversion"),&ins->std.opMacros[2].arMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,minModModeBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Key On/Off"),&ins->std.opMacros[0].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Special"),&ins->std.ex1Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,sid3ControlBits));
macroList.push_back(FurnaceGUIMacroDesc(_("Ring Mod Source"),&ins->std.fmsMacro,0,SID3_NUM_CHANNELS,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroSID3SourceChan));
macroList.push_back(FurnaceGUIMacroDesc(_("Hard Sync Source"),&ins->std.amsMacro,0,SID3_NUM_CHANNELS - 1,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroSID3SourceChan));
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Mod Source"),&ins->std.fbMacro,0,SID3_NUM_CHANNELS - 1,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroSID3SourceChan));
if (!ins->sid3.doWavetable) {
macroList.push_back(FurnaceGUIMacroDesc(_("Feedback"),&ins->std.opMacros[3].arMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
}
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
if (!ins->sid3.doWavetable) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Phase Reset"),&ins->std.opMacros[1].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
}
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope Reset"),&ins->std.opMacros[2].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Attack"),&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Decay"),&ins->std.ex3Macro,0,255,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Sustain"),&ins->std.ex4Macro,0,255,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Sustain Rate"),&ins->std.ex5Macro,0,255,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Release"),&ins->std.ex6Macro,0,255,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
if (!ins->sid3.doWavetable) {
macroList.push_back(FurnaceGUIMacroDesc(_("Noise LFSR bits"),&ins->std.ex7Macro,0,30,16 * 30,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,macroSID3NoiseLFSR,true));
macroList.push_back(FurnaceGUIMacroDesc(_("1-Bit Noise"),&ins->std.opMacros[1].arMacro,0,1,32,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Mix"),&ins->std.ex8Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroSID3WaveMixMode));
} else {
macroList.push_back(FurnaceGUIMacroDesc(_("Sample Mode"),&ins->std.opMacros[1].arMacro,0,1,32,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
}
2024-09-14 00:46:03 -04:00
break;
case DIV_INS_MAX:
case DIV_INS_NULL:
break;
}
2025-03-10 13:46:46 -04:00
drawMacros(macroList,macroEditStateMacros,ins);
2022-02-17 13:08:17 -05:00
ImGui::EndTabItem();
}
2024-08-02 17:52:54 -04:00
if (ins->type==DIV_INS_AY) {
if (!ins->amiga.useSample)
{
if (ImGui::BeginTabItem(_("Timer Macros")))
{
ImGui::Text(_("warning: timer effects are not supported by VGM export!"));
macroList.push_back(FurnaceGUIMacroDesc(_("Timer FX"),&ins->std.ex6Macro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("TFX Offset"),&ins->std.ex7Macro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true));
macroList.push_back(FurnaceGUIMacroDesc(_("Timer Num"),&ins->std.ex8Macro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("Timer Den"),&ins->std.fmsMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(_("PWM Boundary"),&ins->std.amsMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
// workaround, because the gui will not set
// zoom or scroll if we're not in macros tab
ins->temp.vZoom[DIV_MACRO_EX7]=128;
ins->temp.vScroll[DIV_MACRO_EX7]=2048-64;
2025-03-10 13:46:46 -04:00
drawMacros(macroList,macroEditStateMacros,ins);
2024-08-02 17:52:54 -04:00
ImGui::EndTabItem();
}
}
}
if (ins->type==DIV_INS_POWERNOISE || ins->type==DIV_INS_POWERNOISE_SLOPE) {
2024-01-25 12:49:46 -05:00
if (ImGui::BeginTabItem("PowerNoise")) {
int pnOctave=ins->powernoise.octave;
2024-05-26 20:31:17 -04:00
if (ImGui::InputInt(_("Octave offset"),&pnOctave,1,4)) { PARAMETER
2024-01-25 12:49:46 -05:00
if (pnOctave<0) pnOctave=0;
if (pnOctave>15) pnOctave=15;
ins->powernoise.octave=pnOctave;
}
2024-05-26 20:31:17 -04:00
ImGui::Text(_("go to Macros for other parameters."));
2024-01-25 12:49:46 -05:00
ImGui::EndTabItem();
}
}
if (ins->type==DIV_INS_NES ||
ins->type==DIV_INS_AY ||
ins->type==DIV_INS_AY8930 ||
ins->type==DIV_INS_MIKEY ||
ins->type==DIV_INS_PCE ||
ins->type==DIV_INS_X1_010 ||
ins->type==DIV_INS_SWAN ||
ins->type==DIV_INS_VRC6) {
insTabSample(ins);
}
if (ins->type>=DIV_INS_MAX) {
2024-05-26 20:31:17 -04:00
if (ImGui::BeginTabItem(_("Error"))) {
ImGui::Text(_("invalid instrument type! change it first."));
ImGui::EndTabItem();
}
}
2022-02-17 13:08:17 -05:00
ImGui::EndTabBar();
}
if (settings.insEditColorize) {
popAccentColors();
}
2022-02-17 13:08:17 -05:00
}
2022-05-08 19:32:16 -04:00
if (displayMacroMenu) {
displayMacroMenu=false;
if (lastMacroDesc.macro!=NULL) {
ImGui::OpenPopup("macroMenu");
}
}
if (ImGui::BeginPopup("macroMenu",ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings)) {
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("copy"))) {
2022-05-08 19:32:16 -04:00
String mmlStr;
encodeMMLStr(mmlStr,lastMacroDesc.macro->val,lastMacroDesc.macro->len,lastMacroDesc.macro->loop,lastMacroDesc.macro->rel);
SDL_SetClipboardText(mmlStr.c_str());
}
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("paste"))) {
2022-05-08 19:32:16 -04:00
String mmlStr;
char* clipText=SDL_GetClipboardText();
if (clipText!=NULL) {
if (clipText[0]) {
mmlStr=clipText;
}
SDL_free(clipText);
}
if (!mmlStr.empty()) {
decodeMMLStr(mmlStr,lastMacroDesc.macro->val,lastMacroDesc.macro->len,lastMacroDesc.macro->loop,lastMacroDesc.min,(lastMacroDesc.isBitfield)?((1<<(lastMacroDesc.isBitfield?lastMacroDesc.max:0))-1):lastMacroDesc.max,lastMacroDesc.macro->rel);
}
}
ImGui::Separator();
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("clear"))) {
2022-05-08 19:32:16 -04:00
lastMacroDesc.macro->len=0;
lastMacroDesc.macro->loop=255;
lastMacroDesc.macro->rel=255;
2022-05-08 19:32:16 -04:00
for (int i=0; i<256; i++) {
lastMacroDesc.macro->val[i]=0;
}
}
2024-05-26 20:31:17 -04:00
if (ImGui::MenuItem(_("clear contents"))) {
2022-05-08 19:32:16 -04:00
for (int i=0; i<256; i++) {
lastMacroDesc.macro->val[i]=0;
}
}
ImGui::Separator();
2024-05-26 20:31:17 -04:00
if (ImGui::BeginMenu(_("offset..."))) {
ImGui::InputInt(_("X"),&macroOffX,1,10);
ImGui::InputInt(_("Y"),&macroOffY,1,10);
if (ImGui::Button(_("offset"))) {
2022-05-08 19:32:16 -04:00
int oldData[256];
memset(oldData,0,256*sizeof(int));
memcpy(oldData,lastMacroDesc.macro->val,lastMacroDesc.macro->len*sizeof(int));
for (int i=0; i<lastMacroDesc.macro->len; i++) {
int val=0;
bool bit30=false;
2022-05-08 19:32:16 -04:00
if ((i-macroOffX)>=0 && (i-macroOffX)<lastMacroDesc.macro->len) {
bit30=enBit30(oldData[i-macroOffX]);
val=deBit30(oldData[i-macroOffX])+macroOffY;
2022-05-08 19:32:16 -04:00
if (val<lastMacroDesc.min) val=lastMacroDesc.min;
if (val>lastMacroDesc.max) val=lastMacroDesc.max;
}
lastMacroDesc.macro->val[i]=val^(bit30?0x40000000:0);
2022-05-08 19:32:16 -04:00
}
if (lastMacroDesc.macro->loop<lastMacroDesc.macro->len) {
2022-05-08 19:32:16 -04:00
lastMacroDesc.macro->loop+=macroOffX;
} else {
lastMacroDesc.macro->loop=255;
2022-05-08 19:32:16 -04:00
}
if ((lastMacroDesc.macro->rel+macroOffX)>=0 && (lastMacroDesc.macro->rel+macroOffX)<lastMacroDesc.macro->len) {
lastMacroDesc.macro->rel+=macroOffX;
} else {
lastMacroDesc.macro->rel=255;
2022-05-08 19:32:16 -04:00
}
ImGui::CloseCurrentPopup();
}
ImGui::EndMenu();
}
2024-05-26 20:31:17 -04:00
if (ImGui::BeginMenu(_("scale..."))) {
if (ImGui::InputFloat(_("X"),&macroScaleX,1.0f,10.0f,"%.2f%%")) {
2022-05-08 19:32:16 -04:00
if (macroScaleX<0.1) macroScaleX=0.1;
if (macroScaleX>12800.0) macroScaleX=12800.0;
}
2024-05-26 20:31:17 -04:00
ImGui::InputFloat(_("Y"),&macroScaleY,1.0f,10.0f,"%.2f%%");
if (ImGui::Button(_("scale"))) {
2022-05-08 19:32:16 -04:00
int oldData[256];
memset(oldData,0,256*sizeof(int));
memcpy(oldData,lastMacroDesc.macro->val,lastMacroDesc.macro->len*sizeof(int));
lastMacroDesc.macro->len=MIN(255,((double)lastMacroDesc.macro->len*(macroScaleX/100.0)));
2022-05-08 19:32:16 -04:00
for (int i=0; i<lastMacroDesc.macro->len; i++) {
int val=0;
bool bit30=false;
2022-05-08 19:32:16 -04:00
double posX=round((double)i*(100.0/macroScaleX)-0.01);
if (posX>=0 && posX<lastMacroDesc.macro->len) {
val=round((double)deBit30(oldData[(int)posX])*(macroScaleY/100.0));
bit30=enBit30(oldData[(int)posX]);
2022-05-08 19:32:16 -04:00
if (val<lastMacroDesc.min) val=lastMacroDesc.min;
if (val>lastMacroDesc.max) val=lastMacroDesc.max;
}
lastMacroDesc.macro->val[i]=val^(bit30?0x40000000:0);
2022-05-08 19:32:16 -04:00
}
ImGui::CloseCurrentPopup();
}
ImGui::EndMenu();
}
2024-05-26 20:31:17 -04:00
if (ImGui::BeginMenu(_("randomize..."))) {
if (macroRandMin<lastMacroDesc.min) macroRandMin=lastMacroDesc.min;
if (macroRandMin>lastMacroDesc.max) macroRandMin=lastMacroDesc.max;
if (macroRandMax<lastMacroDesc.min) macroRandMax=lastMacroDesc.min;
if (macroRandMax>lastMacroDesc.max) macroRandMax=lastMacroDesc.max;
2024-05-26 20:31:17 -04:00
ImGui::InputInt(_("Min"),&macroRandMin,1,10);
ImGui::InputInt(_("Max"),&macroRandMax,1,10);
if (ImGui::Button(_("randomize"))) {
for (int i=0; i<lastMacroDesc.macro->len; i++) {
int val=0;
if (macroRandMax<=macroRandMin) {
val=macroRandMin;
} else {
val=macroRandMin+(rand()%(macroRandMax-macroRandMin+1));
}
lastMacroDesc.macro->val[i]=val;
}
ImGui::CloseCurrentPopup();
}
ImGui::EndMenu();
}
2022-05-08 19:32:16 -04:00
ImGui::EndPopup();
}
2022-02-17 13:08:17 -05:00
}
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_INS_EDIT;
ImGui::End();
2022-03-22 03:48:48 -04:00
}
void FurnaceGUI::checkRecordInstrumentUndoStep() {
if (insEditOpen && curIns>=0 && curIns<(int)e->song.ins.size()) {
DivInstrument* ins=e->song.ins[curIns];
// invalidate cachedCurIns/any possible changes if the cachedCurIns was referencing a different
// instrument altgoether
bool insChanged=ins!=cachedCurInsPtr;
if (insChanged) {
insEditMayBeDirty=false;
cachedCurInsPtr=ins;
cachedCurIns=*ins;
}
cachedCurInsPtr=ins;
// check against the last cached to see if diff -- note that modifications to instruments
// happen outside drawInsEdit (e.g. cursor inputs are processed and can directly modify
// macro data). but don't check until we think the user input is complete.
bool delayDiff=ImGui::IsMouseDown(ImGuiMouseButton_Left) || ImGui::IsMouseDown(ImGuiMouseButton_Right) || ImGui::GetIO().WantCaptureKeyboard;
if (!delayDiff && insEditMayBeDirty) {
bool hasChange=ins->recordUndoStepIfChanged(e->processTime, &cachedCurIns);
if (hasChange) {
cachedCurIns=*ins;
}
insEditMayBeDirty=false;
}
} else {
cachedCurInsPtr=NULL;
insEditMayBeDirty=false;
}
}
void FurnaceGUI::doUndoInstrument() {
if (!insEditOpen) return;
if (curIns<0 || curIns>=(int)e->song.ins.size()) return;
DivInstrument* ins=e->song.ins[curIns];
// is locking the engine necessary? copied from doUndoSample
e->lockEngine([this,ins]() {
ins->undo();
cachedCurInsPtr=ins;
cachedCurIns=*ins;
});
}
void FurnaceGUI::doRedoInstrument() {
if (!insEditOpen) return;
if (curIns<0 || curIns>=(int)e->song.ins.size()) return;
DivInstrument* ins=e->song.ins[curIns];
// is locking the engine necessary? copied from doRedoSample
e->lockEngine([this,ins]() {
ins->redo();
cachedCurInsPtr=ins;
cachedCurIns=*ins;
});
}